CF445D. Serega and Fun分块

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;
}
posted @ 2024-04-05 02:38  yoshinow2001  阅读(12)  评论(0编辑  收藏  举报