hdu5057 分块法

来源:互联网 发布:知乎jenny wang 事件 编辑:程序博客网 时间:2024/05/18 14:23

题意:n个数,n<=100000,单点修改,区间询问一段内第D位为P的数的个数。内存卡的很死,树状数组会超内存。分块大法好。

每一块为256个数字,(i>>8)即为i所在的块。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#define ll long longusing namespace std;const int maxn=100005;int n,m;int digit[maxn][10];int block[400][10][10];int X,Y,L,R,D,P;int main(){    int x;    char str[10];    int t;    scanf("%d",&t);    while(t--) {        scanf("%d%d",&n,&m);        memset(block,0,sizeof(block));        for(int i=1;i<=n;i++) {            scanf("%d",&x);            int b=(i>>8);            for(int j=1;j<=10;j++) {                digit[i][j]=x%10;                block[b][j][x%10]++;                x/=10;            }        }        for(int i=0;i<m;i++) {            scanf("%s",str);            if(str[0]=='S') {                scanf("%d%d",&X,&Y);                int b=(X>>8);                for(int j=1;j<=10;j++) {                    block[b][j][digit[X][j]]--;                    digit[X][j]=Y%10;                    block[b][j][Y%10]++;                    Y/=10;                }            }            else {                scanf("%d%d%d%d",&L,&R,&D,&P);                int bl=((L-1)>>8)+1,br=((R+1)>>8)-1;                int ans=0;                if(bl<=br) {                    for(int i=bl;i<=br;i++)                        ans+=block[i][D][P];                    for(int i=L;i<(bl<<8);i++)                        ans+=(digit[i][D]==P);                    for(int i=((br+1)<<8);i<=R;i++)                        ans+=(digit[i][D]==P);                }                else {                    for(int i=L;i<=R;i++) {                        ans+=(digit[i][D]==P);                    }                }                printf("%d\n",ans);            }        }    }    return 0;}



0 0
原创粉丝点击