poj 2777 Count Color

用线段树统计染色问题。题意是每次把一个区间的一段区域染上某个色,统计任意区间内有多少种颜色。这题我借鉴了罗前辈的思路,用int型按位记录一个区间内的颜色,修改和查询都是从结点开始,递归操作子区间。不过我最自豪的是,我略加修改了一下,使得我这个线段树不需要建树也能运行,当成功A了以后我特别爽。为什么不建树也行呢?建树本质上就是初始化,而我的代码里tree[1] = 1和向下传递这两个部分已经完成了初始化的任务,也就是说build()被内嵌到change()里面去了。所以即使没有表面上的建树,依然能正确运行。

 1 #include <stdio.h>
 2 #include <string.h>
 3 const int N = 100010;
 4 int tree[N<<2];
 5 inline bool single(int a)
 6 {
 7     return !( (a-1)& a);
 8 }
 9 void change(int u,int x,int y,int s,int t,int n)
10 {
11     int mid = (x+y)>>1,lc = u<<1,rc = lc|1;
12     if(s <= x && y <= t)
13     {
14         tree[u] = 1 << (n-1);
15         return ;
16     }
17     if(tree[u] == 1<<(n-1) )return ;
18     if(single(tree[u]))
19         tree[lc] = tree[rc] = tree[u];
20     if(s <= mid)
21         change(lc,x,mid,s,t,n);
22     if(t >= mid+1)
23         change(rc,mid+1,y,s,t,n);
24     tree[u] = tree[lc] | tree[rc];
25 }
26 void query(int u,int x,int y,int s,int t,int &ans)
27 {
28     int mid = (x+y)>>1,lc = u<<1,rc = lc|1;
29     if( (s <= x && y <= t) || single(tree[u]) )
30     {
31         ans |= tree[u] ;
32         return ;
33     }
34     if(s <= mid)
35         query(lc,x,mid,s,t,ans);
36     if(t >= mid+1)
37         query(rc,mid+1,y,s,t,ans);
38 }
39 int cal(int n)
40 {
41     int m=0;
42     for(int i = 0; i < 30; i++)
43         if( (n>>i) & 1 ) m++;
44     return m;
45 }
46 int main()
47 {
48     int l,n,m,i,a,b,t,ans;
49     char cmd;
50     while(~scanf("%d%d%d",&l,&n,&m))
51     {
52         tree[1] = 1;
53         for(i = 0; i < m; i++)
54         {
55             getchar();
56             scanf("%c",&cmd);
57             if(cmd == 'C')
58             {
59                 scanf("%d%d%d",&a,&b,&t);
60                 if(a > b) a^=b^=a^=b;
61                 change(1,1,l,a,b,t);
62             }
63             else
64             {
65                 scanf("%d%d",&a,&b);
66                 if(a > b) a^=b^=a^=b;
67                 ans = 0;
68                 query(1,1,l,a,b,ans);
69                 printf("%d\n",cal(ans));
70             }
71         }
72     }
73     return 0;
74 }

 本来我是挺得意的,可是che男说,HH大神经常这么做。不带这么打击人的。

原文地址:https://www.cnblogs.com/lzxskjo/p/2654670.html