水牛♂ToTo

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::
这到题的题意很明确,给你L长的离散的带子,初始时都图色1。然后给出O个查询和更新条件。对于这样的题一般用线段树比较好做,而且效率很好。由于颜色比较少,可以用二进制的形式来表示(即所有出入的颜色值都要做这样的处理,把它转化为1左移这么多位所对应的值,即1<<(c-1)),这样在进行颜色合并时就方便多了,直接 A|B。这点搞清楚后,线段树就好写了。
这是我写的代码。
 1 
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 #define MAXN 100001
 6 
 7 struct Seg_Tree{
 8   Seg_Tree *leftptr,*rightptr;
 9   int left,right;
10   int col;
11 }*Root;
12 
13 int L,T,O,cnt;
14 int nmem;
15 Seg_Tree mem[MAXN*10];
16 
17 Seg_Tree* CreateNode(){
18   Seg_Tree* p=&mem[nmem++];
19   memset(p,0,sizeof(Seg_Tree));
20   return p;
21 }
22 
23 Seg_Tree* CreateTree(int s,int e){
24   Seg_Tree* root=CreateNode();
25   root->left=s;
26   root->right=e;
27   if(s!=e){
28     int mid=(s+e)/2;
29     root->leftptr=CreateTree(s,mid);
30     root->rightptr=CreateTree(mid+1,e);
31   }
32   return root;
33 }
34 
35 bool odd(int n){//判断奇偶的,其实就判断是不是只有一种颜色。
36   return (n&(n-1))==0;
37 }
38 
39 void UpdateTree(Seg_Tree* root,int s,int e,int c){
40     if(s<=root->left&&e>=root->right){
41       root->col=c;
42       return;
43     }
44     if(root->col==c) return;
45     if(odd(root->col)){
46       root->leftptr->col=root->col;
47       root->rightptr->col=root->col;
48     }
49     int mid=(root->left+root->right)/2;
50     if(s<=mid) UpdateTree(root->leftptr,s,e,c);
51     if(e>mid) UpdateTree(root->rightptr,s,e,c);
52     root->col=root->leftptr->col|root->rightptr->col;
53 }
54 void Query(Seg_Tree* root,int s,int e,int &cnt){
55     if(s<=root->left&&e>=root->right){
56         cnt=cnt|root->col;
57         return;
58     }
59     if(odd(root->col)){
60         cnt=cnt|root->col;
61         return;
62     }
63   int mid=(root->left+root->right)/2;
64   if(s<=mid) Query(root->leftptr,s,e,cnt);
65   if(e>mid) Query(root->rightptr,s,e,cnt);
66 }
67 int cal(int n){
68   int cnt=0;
69   while(n>0){
70     if(n%2) cnt++;
71     n>>=1;
72   }
73   return cnt;
74 }
75 int main(){
76   nmem=0;
77   scanf("%d%d%d",&L,&T,&O);
78   Root=CreateTree(1,L);
79   UpdateTree(Root,1,L,1);
80   char cmd;
81   int s,e,c;
82   while(O--){
83     scanf(" %c",&cmd);
84     if(cmd=='C'){
85       scanf("%d%d%d",&s,&e,&c);
86       if(s>e) swap(s,e);
87       UpdateTree(Root,s,e,1<<(c-1));
88     }
89     else{
90       cnt=0;
91       scanf("%d%d",&s,&e);
92       if(s>e) swap(s,e);
93       Query(Root,s,e,cnt);
94       printf("%d\n",cal(cnt));
95     }
96   }
97   return 0;
98 }
99 

posted on 2007-11-04 04:01  saintqdd  阅读(937)  评论(2编辑  收藏  举报