CF445D. Serega and Fun分塊

yoshinow2001發表於2024-04-05

link:https://codeforces.com/contest/455/problem/D
不知道為什麼在我收藏題目裡面…翻出來順便做了一下…
題意:給一個序列 \(a\),操作1是shuffle一段區間 \([l,r]\),操作2是查詢區間 \([l,r]\) 有多少值恰好為 \(k\)\(1\leq n,q\leq 10^5\)


不尋常的操作搭配不尋常的詢問方式,有可能是正常的資料結構嗎?(據說Splay好像也可以做~)
於是考慮分塊…
然後就差不多做完了,雙端佇列維護一下(昨天才知道 deque 既可以支援兩頭增刪,也可以下標訪問,對這些STL用的還是太不熟練了QAQ)

實現 : 昨天犯了個非常傻逼的錯誤,對於他同一個塊內的修改操作(迴圈右移)的時候,把一個很簡單的 for(i=r;i>=l+1;i--)v[i]=v[i-1]; 寫成了 for(int i=l+1;i<=r;i++)v[i]=v[i-1]; 然後靜查了很久都沒查出來…

看來平常還是要多注意靜查程式碼,每個小細節都要過一遍(當時覺得應該是其他一些寫得更繁瑣的地方更可能出錯,完全沒看這一句非常簡單並且就一行的程式碼,屬於是犯了明察秋毫但不見輿薪的毛病了…)

// LUOGU_RID: 154191756
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define endl '\n'
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int N=1e5+5;
const int C=405;
int n,q,T,lst,bl[N],L[C],R[C],f[C][N];
vector<deque<int>> v;
int main(){
    fastio;
    cin>>n;
    int S=sqrt(n),T=(n-1)/S+1;
    v=vector<deque<int>>(T+1);
    rep(i,1,n){
        int a;cin>>a;
        bl[i]=(i-1)/S+1;
        v[bl[i]].push_back(a);
        f[bl[i]][a]++;
    }
    rep(i,1,T)L[i]=R[i-1]+1,R[i]=min(S*i,n);
    cin>>q;
    while(q--){
        int op,l,r;
        cin>>op>>l>>r;
        l=(l+lst-1)%n+1;
        r=(r+lst-1)%n+1;
        if(l>r)swap(l,r);
        if(op==1){
            stack<int> S;
            if(bl[l]==bl[r]){
                int D=L[bl[l]],val=v[bl[l]][r-D];
                for(int i=r;i>=l+1;i--)v[bl[l]][i-D]=v[bl[l]][i-1-D];
                v[bl[l]][l-D]=val;
            }else{
                //delete block of r
                rep(i,0,r-L[bl[r]]-1){
                    S.push(v[bl[r]].front());
                    v[bl[r]].pop_front();
                }
                int val=v[bl[r]].front();
                v[bl[r]].pop_front();
                while(!S.empty()){
                    v[bl[r]].push_front(S.top());
                    S.pop();
                }
                f[bl[r]][val]--;

                //insert block of l
                rep(i,0,l-L[bl[l]]-1){
                    S.push(v[bl[l]].front());
                    v[bl[l]].pop_front();
                }
                v[bl[l]].push_front(val);
                while(!S.empty()){
                    v[bl[l]].push_front(S.top());
                    S.pop();
                }
                f[bl[l]][val]++;

                //shuffle
                rep(i,bl[l],bl[r]-1){
                    auto x=v[i].back();
                    f[i][x]--;
                    f[i+1][x]++;
                    v[i].pop_back();
                    v[i+1].push_front(x);
                }
            }
        }else{
            int ans=0,k;
            cin>>k;
            k=(k+lst-1)%n+1;
            if(bl[l]==bl[r]){
                rep(i,l,r)if(v[bl[l]][i-L[bl[l]]]==k)ans++;
            }else{
                rep(i,bl[l]+1,bl[r]-1)ans+=f[i][k];
                rep(i,l,R[bl[l]])if(v[bl[l]][i-L[bl[l]]]==k)ans++;
                rep(i,L[bl[r]],r)if(v[bl[r]][i-L[bl[r]]]==k)ans++;
            }
            cout<<ans<<endl;
            lst=ans;
        }
    }
    return 0;
}

相關文章