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
  • 相关阅读:
    关于同余最短路
    【水】关于 __attribute__
    题解【AtCoder
    一些简单图论问题
    浅谈简单动态规划
    关于博客园主题(美化博客园)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第47章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第46章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第45章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第44章 读书笔记(待更新)
  • 原文地址:https://www.cnblogs.com/shangyu/p/2612509.html
Copyright © 2011-2022 走看看