2021-08-12 SSL 模拟赛 T3
没有标题的第
n
>
=
(
1
0
9
m
o
d
20
)
n>=(10^9 \bmod 20)
n>=(109mod20) 天
思路:
分块,我太菜了,这里转载大佬的思路:
码量巨大
全
!
全!
全!
体
!
体!
体!
起
!
起!
起!
立
!
立!
立!
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<deque>
#include<cstring>
#include<cmath>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
const ll V=1e5+10,N=360;
ll n,m,a[V],f[N][V],cnt,vis[V],c[V],d[V];
ll s,x,y,k,v;
deque<ll> q[N];
char buf[1<<23], *p1=buf, *p2=buf, obuf[1<<23], *O=obuf;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<21, stdin), p1 == p2) ? EOF : *p1++)
void inline read(ll &x)
{
x = 0; char s = getchar();
while (s < '0' || s > '9') s = getchar();
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
}
void put(ll x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) put(x/10);
putchar(x%10+48);
}
void change(ll x,ll y)
{
if(vis[x]==vis[y])
{
ll now=vis[x];
x%=v,y%=v;
if(x==0) x=v;
if(y==0) y=v;
rep(i,1,x-1)
c[i]=q[now].front(),q[now].pop_front();
rep(i,1,v-y)
d[i]=q[now].back(),q[now].pop_back();
ll x=q[now].back();
q[now].pop_back() ,q[now].push_front(x);
per(i,x-1,1) q[now].push_front(c[i]);
rep(i,1,v-y) q[now].push_back(d[v-i-y+1]);
}
else
{
ll k=vis[x],t=x;
while(vis[t+1]==k) ++t;
ll len1=t-x+1;
rep(i,1,len1)
{
c[len1-i+1]=q[k].back();
q[k].pop_back();
--f[k][c[len1-i+1]];
}
ll p=vis[y],h=y;
while(vis[h-1]==p) --h;
ll len2=y-h+1;
rep(i,1,len2)
{
d[i]=q[p].front();
q[p].pop_front() ;
--f[p][d[i]];
}
q[k].push_back(d[len2]);
++f[k][d[len2]] ;
rep(i,1,len1-1)
{
q[k].push_back(c[i]) ;
++f[k][c[i]];
}
per(i,len2-1,1)
{
q[p].push_front(d[i]);
++f[p][d[i]];
}
ll val=q[p-1].back() ;
if(p==k+1) val=c[len1];
q[p].push_front(val),f[p][val]++;
ll ed=c[len1];
rep(i,k+1,p-1)
{
q[i].push_front(ed);++f[i][ed];
ed=q[i].back();
q[i].pop_back();
--f[i][ed];
}
}
}
ll ask(ll x,ll y,ll k)
{
ll res=0;
if(vis[x]==vis[y])
{
ll now=vis[x];
x%=v,y%=v;
if(x==0) x=v;
if(y==0) y=v;
rep(i,1,x-1) //统计不在区间内的合法 k
{
c[i]=q[now].front();
q[now].pop_front();
}
rep(i,1,v-y)
{
d[i]=q[now].back();
q[now].pop_back();
}
per(i,x-1,1)
{
if(c[i]==k) ++res;
q[now].push_front(c[i]);
}
rep(i,1,v-y)
{
if(d[v-y-i+1]==k) ++res;
q[now].push_back(d[v-y-i+1]);
}
res=f[now][k]-res;
}
else
{
ll t=vis[x],u=x;
while(vis[u+1]==t) ++u;
ll len1=u-x+1;
rep(i,1,len1)
{
c[len1-i+1]=q[t].back() ;
q[t].pop_back();
}
ll p=vis[y],h=y;
while(vis[h-1]==p) --h;
ll len2=y-h+1;
rep(i,1,len2)
{
d[i]=q[p].front();
q[p].pop_front() ;
}
rep(i,1,len1)
{
if(c[i]==k) ++res;
q[t].push_back(c[i]);
}
per(i,len2,1)
{
if(d[i]==k) ++res;
q[p].push_front(d[i]);
}
rep(i,t+1,p-1) res+=f[i][k];
}
return res;
}
int main()
{
scanf("%lld%lld",&n,&m);
v=sqrt(n);
rep(i,1,n)
{
read(a[i]);
if(i>cnt*v) ++cnt;
q[cnt].push_back(a[i]);
vis[i]=cnt,++f[cnt][a[i]];
}
rep(i,1,m)
{
read(s),read(x),read(y);
if(s==1) change(x,y);
else
{
read(k);
put(ask(x,y,k));
putchar(10);
}
}
return 0;
}