POJ 2777 Count Color(线段树 区间更新)
根据区间更新的模版改改。线段树真的很不熟悉,交了很多次。
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 using namespace std; 5 #define N 100001 6 #define LL __int64 7 int p[4*N],lz[4*N]; 8 void pushup(int rt) 9 { 10 p[rt] = p[rt<<1]|p[rt<<1|1]; 11 } 12 void pushdown(int rt) 13 { 14 if(lz[rt]) 15 { 16 lz[rt<<1] = lz[rt]; 17 lz[rt<<1|1] = lz[rt]; 18 p[rt<<1] = lz[rt]; 19 p[rt<<1|1] = lz[rt]; 20 lz[rt] = 0; 21 } 22 } 23 void build(int l,int r,int rt) 24 { 25 int m; 26 lz[rt] = 0; 27 if(l == r) 28 { 29 p[rt] = 1; 30 return ; 31 } 32 m = (l+r)>>1; 33 build(l,m,rt<<1); 34 build(m+1,r,rt<<1|1); 35 pushup(rt); 36 } 37 int query(int L,int R,int l,int r,int rt) 38 { 39 int m,ans; 40 ans = 0; 41 if(l >= L&&r <= R) 42 { 43 return p[rt]; 44 } 45 pushdown(rt); 46 m = (l+r)>>1; 47 if(L <= m) 48 ans |= query(L,R,l,m,rt<<1); 49 if(R > m) 50 ans |= query(L,R,m+1,r,rt<<1|1); 51 return ans; 52 53 } 54 void update(int L,int R,int l,int r,int rt,int sc) 55 { 56 int m; 57 if(l >= L &&r <= R) 58 { 59 lz[rt] = sc; 60 p[rt] = sc; 61 return ; 62 } 63 pushdown(rt); 64 m = (l+r)>>1; 65 if(L <= m) update(L,R,l,m,rt<<1,sc); 66 if(R > m) update(L,R,m+1,r,rt<<1|1,sc); 67 pushup(rt); 68 } 69 int main() 70 { 71 int n,m,k,i,a,b,c,ans,t,j; 72 char ch[11]; 73 while(scanf("%d%d%d",&n,&m,&k)!=EOF) 74 { 75 build(1,n,1); 76 for(i = 1;i <= k;i ++) 77 { 78 scanf("%s",ch); 79 if(ch[0] == 'C') 80 { 81 scanf("%d%d%d",&a,&b,&c); 82 if(a > b) swap(a,b); 83 update(a,b,1,n,1,1<<(c-1)); 84 } 85 else 86 { 87 scanf("%d%d",&a,&b); 88 if(a > b) swap(a,b); 89 ans = query(a,b,1,n,1); 90 t = 0; 91 for(j = 0;j < m;j ++) 92 if(ans&(1<<j)) 93 t ++; 94 printf("%d\n",t); 95 } 96 } 97 } 98 return 0; 99 }