hdu 4391 Paint The Wall

来源:互联网 发布:淘宝代理怎么申请 编辑:程序博客网 时间:2024/05/12 08:53

hdu 4391 Paint The Wall


分块hash,当时比赛的时候还不知道是神马东西,解题报告说正解是分块hash,感觉其实不怎么难就是维护这些标记调试要麻烦一点,如果思维不清晰的话肯定是调试不出来的,我的就是一个错误调试了我一个晚上

每个块有一个标记vis,表示当前块的整体颜色,如果为-1则表示当前块不是统一一个颜色,这是mp就起作用了,映射为对应颜色的数量


#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <map>using namespace std;const int maxn=100010;struct Flag{    int vis;    map<int,int> mp;}flag[800];int a[maxn],n,q,block_num,block_size;void rehash(int block_no){    flag[block_no].vis=-1;    int sta=block_no*block_size;    flag[block_no].mp.clear();    for(int i=0;i<block_size&&i+sta<n;i++) flag[block_no].mp[a[sta+i]]++;}void build(){    block_size=(int)sqrt(n*1.0+1e-8);    block_num=n/block_size+(n%block_size!=0);    for(int i=0;i<n;i++)       scanf("%d",&a[i]);    for(int i=0;i<block_num;i++)  rehash(i);}void pushdown(int block_no){    if(flag[block_no].vis!=-1){        flag[block_no].mp.clear();        int sta=block_no*block_size,sz=0;        int &cc=flag[block_no].vis;        for(int i=0;i<block_size&&i+sta<n;i++) a[sta+i]=cc,sz++;        flag[block_no].mp[cc]=sz;        cc=-1;    }}void update(int l,int r,int c){    int lx=l/block_size;    int rx=r/block_size;    if(lx==rx){        pushdown(lx);        for(int i=l;i<=r;i++) a[i]=c;        rehash(lx);    }else{        pushdown(lx);pushdown(rx);        int sta=(lx+1)*block_size;        for(int i=l;i<sta;i++) a[i]=c;        rehash(lx);        sta=rx*block_size;        for(int i=sta;i<=r;i++) a[i]=c;        rehash(rx);        for(int i=lx+1;i<rx;i++) flag[i].vis=c;    }}int query(int l,int r,int c){    int lx=l/block_size;    int rx=r/block_size;    int ret=0;    if(lx==rx){        pushdown(lx);        for(int i=l;i<=r;i++)           ret+= (a[i]==c);    }else{        pushdown(lx);pushdown(rx);        int sta=(lx+1)*block_size;        for(int i=l;i<sta;i++) ret+=(a[i]==c);        sta=rx*block_size;        for(int i=sta;i<=r;i++) ret+=(a[i]==c);        for(int i=lx+1;i<rx;i++)          if(flag[i].vis!=-1){              if(flag[i].vis==c) ret+=block_size;          }          else if(flag[i].mp.find(c)!=flag[i].mp.end()) ret+=flag[i].mp[c];    }    return ret;}int main(){    int id,l,r,c;    while(scanf("%d%d",&n,&q)==2)    {        build();        while(q--)        {            scanf("%d%d%d%d",&id,&l,&r,&c);            if(id==1)  update(l,r,c);            else printf("%d\n",query(l,r,c));        }    }    return 0;}




原创粉丝点击