• zoj 1610 Count the Colors 线段树 区间更新


    题目链接:

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=610

    题意:

    题解:

    线段树区间更新
    注意更新子节点,如果遇到的父节点已经被颜色覆盖掉的话,父节点 的颜色需要往下传递(因为父节点已经不会是原来那种颜色了)。

    代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 #define MS(a) memset(a,0,sizeof(a))
      5 #define MP make_pair
      6 #define PB push_back
      7 const int INF = 0x3f3f3f3f;
      8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
      9 inline ll read(){
     10     ll x=0,f=1;char ch=getchar();
     11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     13     return x*f;
     14 }
     15 //////////////////////////////////////////////////////////////////////////
     16 const int maxn = 8e3+10;
     17 
     18 struct node{
     19     int l,r,col,lazy;
     20 }t[maxn<<2];
     21 
     22 void build(int rt,int l,int r){
     23     t[rt].l=l,t[rt].r=r,t[rt].col=-1,t[rt].lazy=-1;
     24     if(l == r) return ;
     25     int mid = (l+r)/2;
     26     build(rt<<1,l,mid);
     27     build(rt<<1|1,mid+1,r);
     28 }
     29 
     30 void pushdown(int rt){
     31     if(t[rt].lazy != -1){
     32         t[rt<<1].lazy=t[rt<<1|1].lazy = 1;
     33         t[rt<<1].col = t[rt].col;
     34         t[rt<<1|1].col = t[rt].col;
     35         t[rt].lazy = t[rt].col = -1;
     36     }
     37 }
     38 
     39 void update(int rt,int l,int r,int c){
     40     int L=t[rt].l,R=t[rt].r;
     41     if(l<=L && R<=r) {
     42         t[rt].col = c;
     43         t[rt].lazy = 1;
     44         return ;
     45     }
     46     if(t[rt].col == c) return ;
     47     pushdown(rt);
     48     int mid = (L+R)/2;
     49     if(l<=mid) update(rt<<1,l,r,c);
     50     if(r>mid) update(rt<<1|1,l,r,c);
     51 }
     52 
     53 
     54 int vis[maxn<<2],ans[maxn<<2];
     55 
     56 void query(int rt){
     57     int l = t[rt].l,r=t[rt].r;
     58     if(t[rt].lazy == 1){
     59         int c = t[rt].col;
     60         for(int i=l; i<=r; ++i)
     61             vis[i] = c;
     62         return ;
     63     }
     64     if(l == r) return ;
     65     query(rt<<1);  
     66     query(rt<<1|1);  
     67 }
     68 
     69 int main(){
     70     int n;
     71     while(cin>>n){
     72         build(1,1,maxn);
     73         for(int i=0; i<n; i++){
     74             int l,r,c; cin>>l>>r>>c;
     75             update(1,l+1,r,c); 
     76 // 题目每次给的染色段是把[a,b]染成c,之前一直以为就是把a~b的所有点都染成c, 其实不是这样的,
     77 // 要染色的不是点,而是区间,例如要染[0,1],并不是把0,1两点染色,而是把[0,1]这一个单位
     78 // 区间进行染色。 假设有一个样例:
     79 // 1  2  1
     80 // 3  4  1
     81 // 那么这个样例应该输出 1  2  只需要在纸上画一下就可以发现,区间【2,3】是没有被染色的,
     82 // 所以有两个间断的区间颜色是1。
     83 // 解决这个问题的办法是,建立线段树build(1,1,8000),代表区间1~8000, 
     84 // 然后更新时是update(1,1,8000, a+1,b,c);
     85         }
     86 
     87         memset(vis,-1,sizeof(vis)); 
     88         query(1);
     89         int i = 1;  
     90 
     91         MS(ans);  
     92         while(i<maxn){  
     93             int color=vis[i], j=i+1;  
     94             if(color==-1){++i; continue;}  
     95             while(vis[j]!=-1 && vis[j]==color && j<maxn) ++j;  // 统计的是点。。
     96             ++ans[color];  
     97             i=j;  
     98         }  
     99         for(int i=0; i<maxn; ++i)if(ans[i])  
    100             printf("%d %d
    ",i,ans[i]);  
    101         puts("");   
    102     }
    103 
    104     return 0;
    105 }
  • 相关阅读:
    [转载]链接 构造最全的java面试题整理
    [转载]面试技巧问题:面试典型问题回答技巧
    [转载]工作面试时最难的25个问题
    [转载][转]tomcat server.xml配置详解
    [转载]链接 构造最全的java面试题整理
    [转载]转 构造最全的java面试题整理(线程篇)
    [转载]C++ 面试
    [转载]转 构造最全的java面试题整理(线程篇)
    [转载][转]tomcat server.xml配置详解
    [转载]面试技巧问题:面试典型问题回答技巧
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827575.html
Copyright © 2020-2023  润新知