您的位置:首页 > 其它

bzoj2120 数颜色 分块

2016-02-05 22:38 405 查看
据说暴力可过2200ms。。。然而我写分块也才1200ms。。然而很多人写分块跑不过暴力。。。

参考了将狼踩尽(/article/5206358.html)的思路。假设分为m块(注意不是每块m个)。用sum[x][y][z]表示在块x~y中颜色z(经过离散化以后)的个数,val[x][y]表示在x~y块中不同颜色的个数。这样应该就比较容易明白了。

修改:看u会影响那些val[x][y],然后根据sum的值得到val是否要加减,具体看代码;

查询:不能简单的像普通的分块那样进行,要利用现有的。比如查询x~y,它经过的完整的块是u~v,那么我们就可以假设将x~u以及v~y中的颜色插入到val[u][v]中,然后就可以根据修改的模式进行查询了,答案就是val[u][v]。但是最后要复原。

初始化时间复杂度为O(m^2N),修改时最坏经过O(m^2)次,查询主要是零碎部分O(N/m)。总的时间复杂度O(m^2N+M(m^2+N/m)),可以看到,当m=N^(1/3)时时间复杂度最小为O(N^(5/3))。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;

int n,m,size,cnt,tot,blg[20005],a[20005],f[1000005],l[30],r[30],sum[30][30][20005],val[30][30];
void qry(int x,int y){
int i,u=blg[x]+1,v=blg[y]-1;
for (i=x; i<l[u] && i<=y; i++){
if (!sum[u][v][a[i]]) val[u][v]++; sum[u][v][a[i]]++;
}
for (i=y; i>r[v] && i>=x; i--){
if (!sum[u][v][a[i]]) val[u][v]++; sum[u][v][a[i]]++;
}
printf("%d\n",val[u][v]);
for (i=x; i<l[u] && i<=y; i++){
sum[u][v][a[i]]--; if (!sum[u][v][a[i]]) val[u][v]--;
}
for (i=y; i>r[v] && i>=x; i--){
sum[u][v][a[i]]--; if (!sum[u][v][a[i]]) val[u][v]--;
}
}
int main(){
scanf("%d%d",&n,&m); int i,j,k;
size=(int)pow(n,2.0/3); cnt=n/size;
for (i=1; i<=cnt; i++){
l[i]=r[i-1]+1; r[i]=l[i]+size-1;
}
if (r[cnt]<n) r[cnt]=n;
for (i=1; i<=n; i++){
scanf("%d",&k); if (!f[k]) f[k]=++tot; a[i]=f[k];
}
for (i=1; i<=cnt; i++) for (j=l[i]; j<=r[i]; j++) blg[j]=i;
for (i=1; i<=cnt; i++) for (j=i; j<=cnt; j++)
for (k=l[i]; k<=r[j]; k++){
if (!sum[i][j][a[k]]) val[i][j]++; sum[i][j][a[k]]++;
}
while (m--){
char ch=getchar(); while (ch<'A' || ch>'Z') ch=getchar();
int x,y; scanf("%d%d",&x,&y);
if (ch=='Q') qry(x,y); else{
for (i=1; i<=cnt; i++) for (j=i; j<=cnt; j++) if (l[i]<=x && x<=r[j]){
sum[i][j][a[x]]--; if (!sum[i][j][a[x]]) val[i][j]--;
}
if (!f[y]) f[y]=++tot; a[x]=f[y];
for (i=1; i<=cnt; i++) for (j=i; j<=cnt; j++) if (l[i]<=x && x<=r[j]){
if (!sum[i][j][a[x]]) val[i][j]++; sum[i][j][a[x]]++;
}
}
}
return 0;
}

by lych
2016.2 5


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: