• 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
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    根据模板自动生成数据
    CSV to XLSX (专用)
    释放用完的Excel COM组件
    配置文件的力量
    字符编解码的故事(ASCII,ANSI,Unicode,Utf-8区别)
    将结果中的省略号内容全部输出
    Powershell变量的类型
    一些用过的C#类库收集
    运算符
    特殊运算符
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14590579.html
Copyright © 2020-2023  润新知