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;
}