首页 > 代码库 > HDU_5057_分块

HDU_5057_分块

http://acm.hdu.edu.cn/showproblem.php?pid=5057

 

分块,保存每个块中每位对应数字的和,复杂的是getmum,左右下标所在的块不能直接读取block数组,要重新自己计算。

 

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>using namespace std;int a[100005],belong[100005],L[100005],R[100005],block[400][11][10],n,m;int ten[11] = {0,1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};void build(){    int sizee = sqrt(n);    int num = n/sizee;    if(n%sizee)  num++;    for(int i = 1;i <= num;i++)    {        L[i] = (i-1)*sizee+1;        R[i] = i*sizee;    }    for(int i = 1;i <= n;i++)   belong[i] = (i-1)/sizee+1;    for(int i = 1;i <= n;i++)    {        int temp = a[i];        for(int j = 1;j <= 10;j++)        {            block[belong[i]][j][temp%10]++;            temp /= 10;        }    }}int getnum(int l,int r,int d,int p){    int ans = 0;    if(belong[l] == belong[r])    {        for(int i = l;i <= r;i++)        {            if((a[i]/ten[d])%10 == p) ans++;        }        return ans;    }    for(int i = belong[l]+1;i < belong[r];i++)  ans += block[i][d][p];    for(int i = l;i <= R[belong[l]];i++)    {        if((a[i]/ten[d])%10 == p) ans++;    }    for(int i = L[belong[r]];i <= r;i++)    {        if((a[i]/ten[d])%10 == p) ans++;    }    return ans;}void update(int x,int y){    for(int i = 1;i <= 10;i++)    {        block[belong[x]][i][a[x]%10]--;        a[x] /= 10;    }    a[x] = y;    for(int i = 1;i <= 10;i++)    {        block[belong[x]][i][y%10]++;        y /= 10;    }}int main(){    int T;    scanf("%d",&T);    while(T--)    {        memset(block,0,sizeof(block));        scanf("%d%d",&n,&m);        for(int i = 1;i <= n;i++)   scanf("%d",&a[i]);        build();        char s[5];        while(m--)        {            scanf("%s",s);            if(s[0] == S)            {                int x,y;                scanf("%d%d",&x,&y);                update(x,y);            }            else            {                int l,r,d,p;                scanf("%d%d%d%d",&l,&r,&d,&p);                printf("%d\n",getnum(l,r,d,p));            }        }    }    return 0;}

 

HDU_5057_分块