# HDU 4391 Paint The Wall

1. 将 a b 区间染上颜色z
2. 统计a b区间内颜色为z的点的个数

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <map>using namespace std;#define for if(0); else forconst int N=65537*2;struct SegTree{    int a[N<<1],mi[N<<1],mx[N<<1];    int Q;    void init(int n,int c[]){        for(Q=1;Q<=n+2;Q<<=1);        memset(a,0,sizeof(a));        for(int i=Q+0;i<Q+n;i++) a[i]=mi[i]=mx[i]=c[i-Q];        for(int i=Q-1;i>=1;i--) pushup(i);    }    void pushup(int rt) {        a[rt]=a[rt<<1]==a[rt<<1|1]?a[rt<<1]:-1;        mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);        mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);    }    void update_one(int rt,int x) {        a[rt]=mi[rt]=mx[rt]=x;    }    void pushdown(int rt) {        if(a[rt]!=-1) {            update_one(rt<<1,a[rt]);            update_one(rt<<1|1,a[rt]);        }    }    void update(int L,int R,int l,int r,int rt,int c) {        if(a[rt]==c) return;        if(L<=l && r<=R) {            update_one(rt,c);            return;        }        pushdown(rt);        if(rt>=Q) return;        int m=(l+r)>>1;        if(L<=m) update(L,R,l,m,rt<<1,c);        if(m<R) update(L,R,m+1,r,rt<<1|1,c);        pushup(rt);    }    int query(int L,int R,int l,int r,int rt,int c) {        int ret=0;        if(L<=l && r<=R) {            if(c>=mi[rt]&&c<=mx[rt]){                int m=(l+r)>>1;                if(a[rt]!=-1) return (a[rt]==c)?r-l+1:0;                else return query(L,R,l,m,rt<<1,c)+query(L,R,m+1,r,rt<<1|1,c);            }else return 0;        }        if(rt>=Q) return ret;        pushdown(rt);        int m=(l+r)>>1;        if(L<=m) ret+=query(L,R,l,m,rt<<1,c);        if(m<R) ret+=query(L,R,m+1,r,rt<<1|1,c);        return ret;    }}st;int a[N];int n,m;int main() {    while(scanf("%d%d",&n,&m)!=EOF) {        for(int i=0;i<n;i++) scanf("%d",&a[i]);        st.init(n,a);        for(int i=0;i<m;i++) {            int cmd,l,r,c;            scanf("%d%d%d%d",&cmd,&l,&r,&c);            if(cmd==1){                st.update(l,r,0,st.Q-1,1,c);            }else {                printf("%d\n",st.query(l,r,0,st.Q-1,1,c));            }        }    }    return 0;}  分段Hash版(用map<int,int>实现)代码：#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <math.h>#include <map>using namespace std;const int N=100010;const int SQRTN=510;int n,m;int a[N];map<int,int> hash[SQRTN];int flag[SQRTN];int block_size;int block_num;void rehash(int block_no) {    int st=block_no*block_size;    int ed=st+block_size-1;    if(ed>=n) ed=n-1;    hash[block_no].clear();    for(int i=st;i<=ed;i++) {        hash[block_no][a[i]]++;    }    flag[block_no]=-1;}void rebuild(int block_no) {    if(flag[block_no]!=-1) {        int st=block_no*block_size;        int ed=st+block_size-1;        if(ed>=n) ed=n-1;        for(int i=st;i<=ed;i++) a[i]=flag[block_no];        flag[block_no]=-1;    }}void build_hash() {    block_size = int(sqrt(n*1.0)+1.00001);    block_num = n/block_size + ( n%block_size !=0 ) ;    for(int i=0;i<block_num;i++) {        rehash(i);    }}void update_block(int block_no,int sta,int end,int z) {    if(z==flag[block_no]) return;    rebuild(block_no);    int st=block_no*block_size+sta;    int ed=block_no*block_size+end;    if(ed>=n) ed=n-1;    for(int i=st;i<=ed;i++) {        a[i]=z;    }    rehash(block_no);}int get_block(int block_no,int sta,int end,int z) {    if(flag[block_no]!=-1) {        return z==flag[block_no]?end-sta+1:0;    }    int st=block_no*block_size+sta;    int ed=block_no*block_size+end;    if(ed>=n) ed=n-1;    int ret=0;    for(int i=st;i<=ed;i++) {        if(a[i]==z) ret++;    }    return ret;}void update(int l,int r,int z) {    int lx=l/block_size;    int ly=l%block_size;    int rx=r/block_size;    int ry=r%block_size;    if(lx==rx){        update_block(lx,ly,ry,z);    }else{        update_block(lx,ly,block_size-1,z);        update_block(rx,0,ry,z);    }    for(int i=lx+1;i<=rx-1;i++) {        flag[i]=z;    }}int query(int l,int r,int z) {    int lx=l/block_size;    int ly=l%block_size;    int rx=r/block_size;    int ry=r%block_size;    int ret=0;    if(lx==rx){        ret+=get_block(lx,ly,ry,z);    }else{        ret+=get_block(lx,ly,block_size-1,z);        ret+=get_block(rx,0,ry,z);    }    for(int i=lx+1;i<=rx-1;i++) {        if(flag[i]!=-1){            if(z==flag[i]) ret+=block_size;        }else {            if(hash[i].find(z)!=hash[i].end()) ret+=hash[i][z];        }    }    return ret;}int main() {    while(scanf("%d%d",&n,&m)!=EOF) {        for(int i=0;i<n;i++) scanf("%d",&a[i]);        build_hash();        for(int i=0;i<m;i++) {            int cmd,l,r,z;            scanf("%d%d%d%d",&cmd,&l,&r,&z);            if(cmd==1) {                update(l,r,z);            }else if(cmd==2){                printf("%d\n",query(l,r,z));            }        }    }    return 0;}

posted @ 2012-08-26 21:24  编程菜菜  阅读(406)  评论(0编辑  收藏  举报