CF418E Tricky Password
https://www.luogu.com.cn/problem/CF418E
分块
找规律,可以发现每两行(除第一行外)形成一个循环
所以我们只要求解前三行数据就可以了
\[定义:\\
第一行为:a_{1},a_{2},\cdots ,a_{m}\\
第二行为:b_{1},b_{2},\cdots ,b_{m}\\
第三行为:c_{1},c_{2},\cdots ,c_{m}\\
f_{i,j}表示前i块中j在a中出现了几次\\
g_{i,j}表示前i块中j在b中出现了几次\\
\]
修改操作暴力更新该块之后的每个块即可
对于查询操作,由于该点所在的块只有一部分被取到,我们选取前一块的数据,并暴力把该块上一部分有用的数据更新上去,输出答案后删除增加的数据,恢复原状
\(C++ Code:\)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 200005
using namespace std;
int xx,yy,B;
int n,m,k,km,cc,lar,a[N],d[N],l[N],r[N],bel[N];
int x,y,opt,w;
int f[105][200005],g[105][200005];
struct Ques
{
int opt,x,y;
}q[N];
inline int read()
{
int s=0;
char c=getchar();
while (!isdigit(c))
c=getchar();
while (isdigit(c))
{
s=s*10+c-'0';
c=getchar();
}
return s;
}
int main()
{
m=read();
for (int i=1;i<=m;i++)
a[i]=read(),d[i]=a[i];
k=read();
km=m;
for (int i=1;i<=k;i++)
{
q[i].opt=read(),q[i].x=read(),q[i].y=read();
if (q[i].opt==1)
{
swap(q[i].x,q[i].y);
d[++km]=q[i].y;
}
}
sort(d+1,d+km+1);
cc=unique(d+1,d+km+1)-d-1;
for (int i=1;i<=m;i++)
a[i]=lower_bound(d+1,d+cc+1,a[i])-d;
for (int i=1;i<=k;i++)
if (q[i].opt==1)
q[i].y=lower_bound(d+1,d+cc+1,q[i].y)-d;
B=(int)sqrt(m)+1;
if (m/B+1>100)
B=1000;
for (int i=1;i<=m;i++)
{
bel[i]=i/B+1;
if (!l[bel[i]])
l[bel[i]]=i;
r[bel[i]]=i;
}
for (int i=1;i<=bel[m];i++)
{
lar=0;
for (int j=0;j<=cc;j++)
f[i][j]=f[i-1][j],lar=max(lar,f[i-1][j]);
for (int j=0;j<=lar;j++)
g[i][j]=g[i-1][j];
for (int j=l[i];j<=r[i];j++)
{
f[i][a[j]]++;
g[i][f[i][a[j]]]++;
}
}
for (int i=1;i<=k;i++)
{
x=q[i].x,y=q[i].y,opt=q[i].opt;
if (opt==2)
{
if (x==1)
printf("%d\n",d[a[y]]); else
if (x%2==0)
{
w=bel[y]-1;
for (int j=l[w+1];j<=y;j++)
f[w][a[j]]++;
printf("%d\n",f[w][a[y]]);
for (int j=l[w+1];j<=y;j++)
f[w][a[j]]--;
} else
{
w=bel[y]-1;
for (int j=l[w+1];j<=y;j++)
f[w][a[j]]++,g[w][f[w][a[j]]]++;
printf("%d\n",g[w][f[w][a[y]]]);
for (int j=l[w+1];j<=y;j++)
g[w][f[w][a[j]]]--,f[w][a[j]]--;
}
} else
{
w=bel[x];
for (int j=w;j<=bel[m];j++)
{
g[j][f[j][a[x]]]--;
f[j][a[x]]--;
}
a[x]=y;
for (int j=w;j<=bel[m];j++)
{
f[j][a[x]]++;
g[j][f[j][a[x]]]++;
}
}
}
return 0;
}