zoukankan      html  css  js  c++  java
  • poj2777Count Color(线段树 成段更新)

    http://poj.org/problem?id=2777

    网上的一段解释

    经典的线段树题目。成段更新,在利用一个数组在查询顺次整段区间时,登记未曾被遮蔽到的颜色,并对其所对应的编号符号为1.而在成段更新结点时,若某区间将揭示混杂色,就让其子节点更新为它的颜色,并符号该结点。总之,对于成段更新区间属性的题目等闲用线段树来处理,利用时要保留结点属性的单一性,但更新摧毁了这种单一性时,则应递归地坚持该结点孩子的属性的单一性。只有这么,在更新垄断才不至于退化到O(n)的混杂度,保证高效率。

    View Code
      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include<string.h>
      5 using namespace std;
      6 int s[300010];
      7 int x,co[32];
      8 void ctree(int l,int r,int w)
      9 {
     10     if(l==r)
     11     {
     12         s[w] = 1;
     13         return ;
     14     }
     15     int m = (l+r)/2;
     16     ctree(l,m,2*w);
     17     ctree(m+1,r,2*w+1);
     18 }
     19 void add(int a,int b,int l,int r,int w)
     20 {
     21     if(l==a&&b==r)
     22     {
     23         s[w] = x;
     24     }
     25     else
     26     {
     27         int m = (l+r)/2;
     28         if(s[w]>0)
     29         {
     30             s[2*w] = s[w];
     31             s[2*w+1] = s[w];
     32             s[w] = -1;
     33         }
     34         if(b<=m)
     35         add(a,b,l,m,2*w);
     36         else
     37         if(a>m)
     38         add(a,b,m+1,r,2*w+1);
     39         else
     40         {
     41             add(a,m,l,m,2*w);
     42             add(m+1,b,m+1,r,2*w+1);
     43         }
     44     }
     45 }
     46 void search(int a,int b,int l,int r,int w)
     47 {
     48     if(s[w]>0)
     49     co[s[w]] = 1;
     50     else
     51     {
     52         int m = (l+r)/2;
     53         if(b<=m)
     54         search(a,b,l,m,2*w);
     55         else
     56         if(a>m)
     57         search(a,b,m+1,r,2*w+1);
     58         else
     59         {
     60             search(a,m,l,m,2*w);
     61             search(m+1,b,m+1,r,2*w+1);
     62         }
     63     }
     64 }
     65 int main()
     66 {
     67     int a,b,i,j,t,l,o,m,h,num;
     68     char c[10];
     69     scanf("%d%d%d", &l,&t,&o);
     70     ctree(1,l,1);
     71     s[1] = 1;
     72     while(o--)
     73     {
     74         scanf("%s",&c);
     75         if(c[0] == 'P')
     76         {
     77             scanf("%d%d", &a,&b);
     78             if(a>b)
     79             {
     80                 h = a;
     81                 a = b;
     82                 b = h;
     83             }
     84             num = 0;
     85             memset(co,0,sizeof(co));
     86             search(a,b,1,l,1);
     87             for(i = 1; i <= t ; i++)
     88             {
     89                 if(co[i])
     90                 num++;
     91                 //printf("%d]",co[i]);
     92             }
     93             printf("%d\n",num);
     94         }
     95         else
     96         {
     97             scanf("%d%d%d",&a,&b,&x);
     98             add(a,b,1,l,1);
     99         }
    100     }
    101     return 0;
    102 }
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include<stdlib.h>
     5 #include<iostream>
     6 using namespace std;
     7 #define N 100010
     8 int s[N<<2],n,t,m,co[31];
     9 void build(int l,int r,int w)
    10 {
    11     if(l==r)
    12     {
    13         s[w] = 1;
    14         return ;
    15     }
    16     int m = (l+r)>>1;
    17     build(l,m,w<<1);
    18     build(m+1,r,w<<1|1);
    19 }
    20 void add(int a,int b,int d,int l,int r,int w)
    21 {
    22     if(a<=l&&b>=r)
    23     {
    24        s[w] = d;
    25        return ;
    26     }
    27     if(s[w]>0)
    28     {
    29         s[w<<1] = s[w];
    30         s[w<<1|1] = s[w];
    31         s[w] = -1;
    32     }
    33     int m = (l+r)>>1;
    34     if(a<=m) add(a,b,d,l,m,w<<1);
    35     if(b>m)  add(a,b,d,m+1,r,w<<1|1);
    36 }
    37 void query(int a,int b,int l,int r,int w)
    38 {
    39     if(s[w]>0)
    40     {
    41         co[s[w]] = 1;
    42         return ;
    43     }
    44     int m = (l+r)>>1;
    45     if(a<=m) query(a,b,l,m,w<<1);
    46     if(b>m)  query(a,b,m+1,r,w<<1|1);
    47 }
    48 int main()
    49 {
    50     int i,a,b,d,num;
    51     char c[10];
    52     while(cin>>n>>t>>m)
    53     {
    54         build(1,n,1);
    55         s[1] = 1;
    56         while(m--)
    57         {
    58             scanf("%s",&c);
    59             if(c[0]=='C')
    60             {
    61                 scanf("%d%d%d",&a,&b,&d);
    62                 int y = max(a,b);
    63                 int x = min(a,b);
    64                 add(x,y,d,1,n,1);
    65             }
    66             else
    67             {
    68                 scanf("%d%d",&a,&b);
    69                 int y = max(a,b);
    70                 int x = min(a,b);
    71                 num=0;
    72                 memset(co,0,sizeof(co));
    73                 query(x,y,1,n,1);
    74                 for(i = 1; i <= t ; i++)
    75                 if(co[i]) num++;
    76                 printf("%d\n",num);
    77             }
    78         }
    79     }
    80 }
    View Code
  • 相关阅读:
    头像点击预览代码
    知识总结和记录——Bootstrap
    知识总结和记录——HTML
    知识总结和记录——面向对象
    知识总结和记录——递归
    知识总结和记录——迭代器和生成器
    知识总结和记录——内置函数
    zap 学习笔记
    2020年总结
    学习笔记_Linux常用指令
  • 原文地址:https://www.cnblogs.com/shangyu/p/2612509.html
Copyright © 2011-2022 走看看