• poj2777( Count Color)


    题目地址:Count Color

    题目大意:

          给一个划分为L的线段染色,有两种操作,一种C操作 给定l,r区间染色为val。另一种操作P 查询l,r区间的颜色有多少种。

    解题报告:

          线段树,区间更新。

    这题的lazy 表示该区间颜色种类,如果单色则为“1”,如果多色为”0“。tag 代表该区间的哪一种颜色。如果修改区间的颜色时,判断修改的颜色和该区间的颜色是否相同,相同的话就return,如果直接找到该区间,直接lazy赋值为”1“,tag 赋值为”v“,不用往下递归,因为该区间包含下面的子区间的单色,所以查询的时候,只需要看从根区间往下递归,只要遇到单色区间,就说明往下的子区间也就一定是该颜色。

     注意:线段数核心查询区间,不要访问到每个叶子节点会TLE。

             线段数被调里尽量不要有循环会TLE。(这题在建树和updata里插了了31的循环就TLE了)

             注意线段树从大区间往下分离成两个小区间,如果是染色,查到大区间的染色情况单色就能确定以下子区间的染色,否则往下递归继续查询。

             注意lazy的使用。

    代码:

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <cstdio>
      7 #include <string>
      8 #include <bitset>
      9 #include <vector>
     10 #include <queue>
     11 #include <stack>
     12 #include <cmath>
     13 #include <list>
     14 #include <map>
     15 #include <set>
     16 using namespace std;
     17 /***************************************/
     18 #define ll long long
     19 #define int64 __int64
     20 /***************************************/
     21 const int INF = 0x7f7f7f7f;
     22 const double eps = 1e-8;
     23 const double PIE=acos(-1.0);
     24 const int d1x[]= {0,-1,0,1};
     25 const int d1y[]= {-1,0,1,0};
     26 const int d2x[]= {0,-1,0,1};
     27 const int d2y[]= {1,0,-1,0};
     28 const int fx[]= {-1,-1,-1,0,0,1,1,1};
     29 const int fy[]= {-1,0,1,-1,1,-1,0,1};
     30 /***************************************/
     31 void openfile()
     32 {
     33     freopen("data.in","rb",stdin);
     34     freopen("data.out","wb",stdout);
     35 }
     36 /**********************华丽丽的分割线,以上为模板部分*****************/
     37 const int M=100100;
     38 
     39 struct tree
     40 {
     41     int left,right;
     42     int lazy,tag; //lazy储存该区间的颜色是否单色,单色为1 多色为0
     43                   //tag 记录该区间的颜色为哪种
     44 } node[M*4];
     45 
     46 int cnt;
     47 int p[31];
     48 void build__tree(int id,int l,int r)
     49 {
     50     int mid=(l+r)/2;
     51     node[id].lazy=1;
     52     node[id].tag=1;
     53     node[id].left=l;
     54     node[id].right=r;
     55     if (l==r)
     56         return ;
     57     build__tree(id*2,l,mid);
     58     build__tree(id*2+1,mid+1,r);
     59 }
     60 void updata(int id,int l,int r,int v)
     61 {
     62     int mid=(node[id].left+node[id].right)/2;
     63     if (node[id].left==l&&node[id].right==r)//区间染色
     64     {
     65         node[id].lazy=1;
     66         node[id].tag=v;
     67         return ;
     68     }
     69     if (node[id].tag==v&&node[id].lazy)  //如果该区间和即将染色的区间颜色相同,并且单色则不用进行
     70         return ;
     71     if (node[id].lazy) // 单色且染色不同,需要进行lazy操作
     72     {
     73         node[id].lazy=0; //标记多色
     74         updata(id*2,node[id].left,mid,node[id].tag);
     75         updata(id*2+1,mid+1,node[id].right,node[id].tag);
     76     }
     77     if (r<=mid)
     78         updata(id*2,l,r,v);
     79     else if (l>mid)
     80         updata(id*2+1,l,r,v);
     81     else
     82     {
     83         updata(id*2,l,mid,v);
     84         updata(id*2+1,mid+1,r,v);
     85     }
     86 }
     87 void query(int id,int l,int r)
     88 {
     89     int mid=(node[id].left+node[id].right)/2;
     90     if (node[id].lazy)  //该区间为单色,说明子区间为同样颜色。
     91     {
     92         p[node[id].tag]=1;
     93         return;
     94     }
     95     if (r<=mid)
     96         query(id*2,l,r);
     97     else if (l>mid)
     98         query(id*2+1,l,r);
     99     else
    100     {
    101         query(id*2,l,mid);
    102         query(id*2+1,mid+1,r);
    103     }
    104 }
    105 int main()
    106 {
    107     int l,t,o;
    108     while(scanf("%d%d%d",&l,&t,&o)!=EOF)
    109     {
    110         int i,j;
    111         build__tree(1,1,l);
    112         while(o--)
    113         {
    114             char c;
    115             int x,y,val;
    116             getchar();
    117             scanf("%c",&c);
    118             if (c=='C')
    119             {
    120                 scanf("%d%d%d",&x,&y,&val);
    121                 if (x>y)
    122                     swap(x,y);
    123                 updata(1,x,y,val);
    124             }
    125             if (c=='P')
    126             {
    127                 cnt=0;
    128                 memset(p,0,sizeof(p));
    129                 scanf("%d%d",&x,&y);
    130                 if (x>y)
    131                     swap(x,y);
    132                 query(1,x,y);
    133                 for(int i=1;i<31;i++)
    134                     if (p[i])
    135                         cnt++;
    136                 printf("%d
    ",cnt);
    137             }
    138         }
    139 
    140     }
    141     return 0;
    142 }
    143 
    144 /*
    145 2 2 100
    146 C 1 1 2
    147 P 1 2
    148 C 2 2 2
    149 P 1 2
    150 C 2 2 2
    151 P 1 2
    152 C 1 1 2
    153 P 1 2
    154 C 1 2 2
    155 P 1 2
    156 C 1 2 1
    157 
    158 5 3 1000
    159 C 2 3 2
    160 C 2 4 3
    161 C 3 5 2
    162 C 2 3 1
    163 C 1 3 2
    164 P 1 5
    165 
    166 5 3 1000
    167 P 1 5
    168 C 2 3 2
    169 P 1 5
    170 C 2 4 3
    171 P 1 5
    172 C 3 5 2
    173 P 1 5
    174 C 2 3 1
    175 P 1 5
    176 C 1 3 2
    177 P 1 5
    178 C 4 4 3
    179 P 1 5
    180 */
    View Code
  • 相关阅读:
    hdu 1175
    hdu 2197
    STL的学习
    数据结构之线性结构栈
    Linux下Fork与Exec使用
    散列技术之哈希
    检索之二分检索
    检索之顺序检索
    程序员该怎样放松?8个好网站推荐
    外部碎片和内部碎片的区别
  • 原文地址:https://www.cnblogs.com/ZhaoPengkinghold/p/4073312.html
Copyright © 2020-2023  润新知