zoukankan      html  css  js  c++  java
  • HDU 5023线段树区间染色,统计区间内颜色个数

     这个也是一个线段树的模板

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #include<set>
    using namespace std;
    const int maxx = 1000050;
    set<int>s;
    struct node{
       int color;
       int left;
       int right;
       int mid;
    }a[maxx<<2];
    void pushdown(int root){
      if(a[root].color){//把修改到两个子节点,并重新把laze清空
        a[root<<1].color=a[root].color;
        a[root<<1|1].color=a[root].color;
        a[root].color=0;
      }
    }
    void buildtree(int root,int l,int r)
    {
         int mid=(l+r)>>1;
         a[root].left=l;
         a[root].right=r;
         a[root].mid=mid;
         a[root].color=2;
         if(l==r)return;
         buildtree(root*2,l,mid);
         buildtree(root*2+1,mid+1,r);
    }
    void update(int root,int l,int r,int c){
       if (a[root].left == l && a[root].right == r){
          a[root].color=c;//满足延时标记所满足的区间
           return;
       }
       if (a[root].color==c)return;
       pushdown(root);//所更新的区间比较小,我们可以把修改push下去
       if(l>a[root].mid)update(root<<1|1,l,r,c);//所求区间在现在的区间的右边,所以选择当前节点的右儿子
       else if (r<=a[root].mid)update(root<<1,l,r,c);//在左边,选择左儿子
       else {//通过中间节点进行二分
            update(root<<1,l,a[root].mid,c);
            update(root<<1|1,a[root].mid+1,r,c);
       }
    }
    void query(int root,int l,int r){
       if (a[root].color){//当前的laze标记已经标记到这个位置
         s.insert(a[root].color);
         return;
       }
       //如果没有到这个位置代表需要往下找 同理
       if (l > a[root].mid)query(root<<1|1,l,r);
       else if (r<=a[root].mid)query(root<<1,l,r);
       else{
          query(root<<1,l,a[root].mid);
          query(root<<1|1,a[root].mid+1,r);
       }
    }
    int main(){
      int n,m;
      int l,r,c;
      char op[10];
      while(~scanf("%d%d",&n,&m) &&(n+m)){
        buildtree(1,1,n);
        for (int i=0;i<m;i++){
          scanf("%s%d%d",op,&l,&r);
          if(op[0]=='P'){
            scanf("%d",&c);
            update(1,l,r,c);
          }else{
             s.clear();
             query(1,l,r);
             int ss=s.size();
            set<int>::iterator it;
             for (it=s.begin();it!=s.end();it++){
                printf("%d",*it);
                if (ss>1)printf(" ");
                ss--;
             }
             printf("
    ");
          }
        }
      }
      return 0;
    }

    题,只需要添加laze标记,并且在不断的维护中,保存更新并pushdown下去,然后为了避免重复,搞一个set就行。

    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    Promise.all和Promise.race区别,和使用场景
    使用Promise解决多层异步调用的简单学习【转】
    前端性能优化-缓存
    Node.js机制及原理理解初步【转】
    微信小程序 canvas 字体自动换行(支持换行符)
    百度地图-鼠标悬停样式
    文件I/O相关函数
    获取系统限制信息
    标准C头文件
    数据库系统小结:(不包括详细知识点,更像一个大纲)
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/10325239.html
Copyright © 2011-2022 走看看