CF455D Serega and Fun(deque+分块)

这道题强制在线,那么考虑在线算法

好像复杂度低的可以使用平衡树,但是我们这里使用分块算法 因为数据量不是特别大

因为是在前面加一个后面删一个,所以我们考虑使用双端队列来维护这个信息

这样修改的时候,可以把前面的块的末尾加到后面的块,这样每块的大小都不会发生改变

CF455D Serega and Fun(deque+分块)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=1e5+10;
const int mod=1e9+7;
int block;
deque<int> q[330];
int a[N],cnt[330][N];
int n;
void init(){
    int i;
    for(i=1;i<=n;i++){
        int pos=(i-1)/block+1;
        cnt[pos][a[i]]++;
        q[pos].push_back(a[i]);
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n;
    block=sqrt(n);
    int i;
    for(i=1;i<=n;i++)
        cin>>a[i];
    init();
    int qu;
    cin>>qu;
    ll ans=0;
    while(qu--){
        int opt,l,r,k;
        cin>>opt>>l>>r;
        l=((l+ans-1)%n)+1;
        r=((r+ans-1)%n)+1;
        if(l>r)
            swap(l,r);
        int idx1=(l-1)/block+1;
        int idx2=(r-1)/block+1;
        if(opt==1){
            if(idx1==idx2){
                int pos=l-(idx1-1)*block-1;
                int pos1=r-(idx1-1)*block-1;
                int x=q[idx1][pos1];
                q[idx1].erase(q[idx1].begin()+pos1);
                q[idx1].insert(q[idx1].begin()+pos,x);
            }
            else{
                for(i=idx1;i<idx2;){
                    int x=q[i].back();
                    q[i].pop_back();
                    cnt[i][x]--;
                    i++;
                    q[i].push_front(x);
                    cnt[i][x]++;
                }
                int pos=r-(idx2-1)*block;
                int x=q[idx2][pos];
                q[idx2].erase(q[idx2].begin()+pos),cnt[idx2][x]--;
                pos=l-(idx1-1)*block-1;
                q[idx1].insert(q[idx1].begin()+pos,x),cnt[idx1][x]++;
            }
        }
        else{
            cin>>k;
            k=((k+ans-1)%n)+1;
            ans=0;
            if(idx1==idx2){
                int pos=l-(idx1-1)*block-1;
                int pos1=r-(idx1-1)*block-1;
                for(i=pos;i<=pos1;i++){
                    if(q[idx1][i]==k){
                        ans++;
                    }
                }
            }
            else{
                int pos=l-(idx1-1)*block-1;
                int pos1=r-(idx2-1)*block-1;
                for(i=pos;i<q[idx1].size();i++){
                    if(q[idx1][i]==k)
                        ans++;
                }
                for(i=0;i<=pos1;i++){
                    if(q[idx2][i]==k)
                        ans++;
                }
                for(i=idx1+1;i<idx2;i++){
                    ans+=cnt[i][k];
                }
            }
            cout<<ans<<endl;
        }
    }
}
View Code

 

上一篇:B-1059 C语言竞赛 (20 分)


下一篇:1059.C语言竞赛-PAT乙级