• HDU 3397 Sequence operation(线段树区间染色加区间合并)


    妈的调了两天终于过了。。。我好菜啊。

    题意

    对长度为n的序列执行q种操作,

    0:把区间内的值都置为0;

    1:把区间内的值都置为1;

    2:把区间内的0都置为1,区间内的1都置为0;

    3:查询区间里1的个数;

    4:查询区间里最长的连续为1的区间的长度;

    题解

    显然,线段树区间更新区间查询可解此题,具体是:

    维护懒标标记set,区间里1的个数sum1,区间左端点l,区间右端点r,区间里最长的连续为1的区间的长度sub,区间里最长的连续为0的区间的长度zsub,区间里以左端点为起点的连续为1的区间的长度lsub1,区间里以左端点为起点的连续为0的区间的长度lsub0,区间里以又端点为起点的连续为1的区间的长度rsub1,区间里以右端点为起点的连续为0的区间的长度rsub0,区间里以左端点为起点的连续为1的区间的长度lsub1。把这十个给维护好就行了呀。

      1 #define dbg(x) cout<<#x<<" = "<< (x)<< endl
      2 #define IO std::ios::sync_with_stdio(0);
      3 #include <bits/stdc++.h>
      4 #define iter ::iterator
      5 using namespace  std;
      6 typedef long long ll;
      7 typedef pair<ll,ll>P;
      8 #define pb push_back
      9 #define se second
     10 #define fi first
     11 #define rs o<<1|1
     12 #define ls o<<1
     13 const ll inf=0x7fffffff;
     14 const int N=1e5+10;
     15 struct node{
     16     int sum1,lsub0,lsub1,rsub0,rsub1;
     17     int l,r,sub,zsub;
     18     int set;
     19 }a[N*4];
     20 void push(int o,int l,int r){
     21     int g=r-l+1;
     22     int gl=a[ls].r-a[ls].l+1;
     23     int gr=a[rs].r-a[rs].l+1;
     24     a[o].sum1=a[ls].sum1+a[rs].sum1;
     25     a[o].lsub0=a[ls].lsub0;
     26     a[o].rsub0=a[rs].rsub0;
     27 
     28     if(a[o].lsub0==gl){
     29         a[o].lsub0+=a[rs].lsub0;
     30     }
     31     if(a[o].rsub0==gr){
     32         a[o].rsub0+=a[ls].rsub0;
     33     }
     34     a[o].lsub1=a[ls].lsub1;
     35     a[o].rsub1=a[rs].rsub1;
     36     if(a[o].lsub1==gl){
     37         a[o].lsub1+=a[rs].lsub1;
     38     }
     39     if(a[o].rsub1==gr){
     40         a[o].rsub1+=a[ls].rsub1;
     41     }
     42     a[o].sub=max(a[ls].rsub1+a[rs].lsub1,max(a[ls].sub,a[rs].sub));
     43     a[o].zsub=max(a[ls].rsub0+a[rs].lsub0,max(a[ls].zsub,a[rs].zsub));
     44 }
     45 void sw(int o,int l,int r){
     46     int g=r-l+1;
     47     a[o].set=1-a[o].set;
     48     a[o].sum1=g-a[o].sum1;
     49     swap(a[o].lsub0,a[o].lsub1);
     50     swap(a[o].rsub0,a[o].rsub1);
     51     swap(a[o].sub,a[o].zsub);
     52 }
     53 void down(int o,int l,int r){
     54     int g=r-l+1;
     55     int gl=a[ls].r-a[ls].l+1;
     56     int gr=a[rs].r-a[rs].l+1;
     57     int x=a[o].set;
     58     if(x==-1)return;
     59     if(x<2){
     60         a[ls].set=a[rs].set=x;
     61         a[ls].lsub1=a[ls].rsub1=a[ls].sum1=a[ls].sub=x?gl:0;
     62         a[rs].lsub1=a[rs].rsub1=a[rs].sum1=a[rs].sub=x?gr:0;
     63         a[ls].lsub0=a[ls].rsub0=a[ls].zsub=x?0:gl;
     64         a[rs].lsub0=a[rs].rsub0=a[rs].zsub=x?0:gr;
     65         a[o].set=-1;
     66     }
     67     else{
     68         a[o].set=-1;
     69         int m=(l+r)/2;
     70         sw(ls,l,m);
     71         sw(rs,m+1,r);
     72     }
     73 }
     74 void build(int o,int l,int r){
     75     a[o].set=-1;
     76     if(l==r){
     77         int x;
     78         scanf("%d",&x);
     79         a[o].l=a[o].r=l;
     80         a[o].sum1=a[o].lsub1=a[o].rsub1=a[o].sub=x;
     81         a[o].lsub0=a[o].rsub0=a[o].zsub=1-x;
     82         return;
     83     }
     84     int m=(l+r)/2;
     85     build(ls,l,m);
     86     build(rs,m+1,r);
     87     a[o].l=a[ls].l;
     88     a[o].r=a[rs].r;
     89     push(o,l,r);
     90 }
     91 void up(int o,int l,int r,int ql,int qr,int k){
     92     int g=r-l+1;
     93     int gl=a[ls].r-a[ls].l+1;
     94     int gr=a[rs].r-a[rs].l+1;
     95     if(l>=ql&&r<=qr){
     96         if(k<2){
     97             a[o].set=k;
     98             a[o].lsub1=a[o].rsub1=a[o].sub=a[o].sum1=k?g:0;
     99             a[o].lsub0=a[o].rsub0=a[o].zsub=k?0:g;
    100         }
    101         else sw(o,l,r);
    102         return;
    103     }
    104     down(o,l,r);
    105     int m=(l+r)/2;
    106     if(ql<=m)up(ls,l,m,ql,qr,k);
    107     if(qr>m)up(rs,m+1,r,ql,qr,k);
    108     push(o,l,r);
    109 }
    110 int qu(int o,int l,int r,int ql,int qr,int k){
    111     if(k==3){
    112         if(l>=ql&&r<=qr){
    113             return a[o].sum1;
    114         }
    115         down(o,l,r);
    116         int m=(l+r)/2;
    117         int res=0;
    118         if(ql<=m)res+=qu(ls,l,m,ql,qr,k);
    119         if(qr>m)res+=qu(rs,m+1,r,ql,qr,k);
    120         return res;
    121     }
    122     if(l>=ql&&r<=qr){
    123         return a[o].sub;
    124     }
    125     down(o,l,r);
    126     int m=(l+r)/2;
    127     int res=min(a[ls].rsub1,m-ql+1)+min(a[rs].lsub1,qr-m);
    128     if(ql<=m)res=max(res,qu(ls,l,m,ql,qr,k));
    129     if(qr>m)res=max(res,qu(rs,m+1,r,ql,qr,k));
    130     return res;
    131 }
    132 int T,n,q;
    133 int main(){
    134     scanf("%d",&T);
    135     while(T--){
    136         scanf("%d%d",&n,&q);
    137         build(1,1,n);
    138         while(q--){
    139             int k,l,r;
    140             scanf("%d%d%d",&k,&l,&r);
    141             l++;
    142             r++;
    143             if(k<=2)up(1,1,n,l,r,k);
    144             else printf("%d
    ",qu(1,1,n,l,r,k));
    145         }
    146     }
    147 }  
  • 相关阅读:
    关于字符的C++函数
    VC6 LINK : fatal error LNK1168: cannot open Debug/Test.exe for writing
    1019 数字黑洞 (20)
    1015 德才论 (25)
    1013 数素数 (20)(20 分)
    1003 我要通过!(20)(20 分)
    今日目标
    MySQL单列索引和组合索引的区别
    Struts2中过滤器和拦截器的区别
    SQL 统计 字段 竖向转横向 (行转列)显示
  • 原文地址:https://www.cnblogs.com/ccsu-kid/p/10661820.html
Copyright © 2020-2023  润新知