zoukankan      html  css  js  c++  java
  • hdu3397 Sequence operation

         感觉自己好像搞定了一个不得了得题呢。。

        对于这种区间性质合并的线段树,对于每个节点保存一下当前区间内1的个数,左右边界相邻的1个的个数与0的个数,还有当前区间最大连续的1和0的个数.

        合并的时候的细节:

        1.如果lson的右边界是1并且rson的左边界是1,那么当前节点的最大连续1的值应该更新为tr[n].res=max(tr[n].res,tr[LL].r+tr[RR].l);

        2.如果lson的连续1的个数等于它所表示的区间大小(这段区间的值全为1),那么当前节点的左区间连续1的个数应该更新为tr[n].l+=tr[RR].l;对于右区间的连续1的个数更新也一样。

        3.对于区间中0的性质更新与1一样

        更新时候的细节

        1.如果当前进行的是区间覆盖,那么是需要吧区间翻转的标记置0的。

        2.如果当前既需要更新区间覆盖与区间翻转,这时候只有一种可能情况就是区间覆盖是先进行赋值过的,所以在pushdown的时候区间覆盖应该先进行。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define LL n<<1
      4 #define RR n<<1|1
      5 #define lson l,mid,LL
      6 #define rson mid+1,r,RR
      7 #define mid ((l+r)/2)
      8 const int maxn=500005;
      9 struct node{
     10     int res,ret,num,l,r,ll,rr;//最长连续1的长度,最长连续0的长度,区间内1的个数,区间内左右边界连续1的个数,0的个数 
     11 };
     12 node tr[maxn<<2];
     13 int lazy[maxn<<2];//区间覆盖懒惰标记 
     14 int chan[maxn<<2];//区间翻转懒惰标记 
     15 int a[maxn];
     16 void up(int l,int r,int n){
     17     tr[n].num=tr[LL].num+tr[RR].num;
     18     tr[n].res=max(tr[LL].res,tr[RR].res);
     19     tr[n].ret=max(tr[LL].ret,tr[RR].ret);
     20     tr[n].l=tr[LL].l;
     21     tr[n].ll=tr[LL].ll;
     22     tr[n].r=tr[RR].r;
     23     tr[n].rr=tr[RR].rr;
     24     if(tr[LL].r&&tr[RR].l)
     25     {
     26         tr[n].res=max(tr[n].res,tr[LL].r+tr[RR].l);
     27         if(mid-l+1==tr[LL].res)
     28         tr[n].l+=tr[RR].l;
     29         if(r-mid==tr[RR].res)
     30         tr[n].r+=tr[LL].r;
     31     }
     32     if(tr[LL].rr&&tr[RR].ll)
     33     {
     34         tr[n].ret=max(tr[n].ret,tr[LL].rr+tr[RR].ll);
     35         if(mid-l+1==tr[LL].ret)
     36         tr[n].ll+=tr[RR].ll;
     37         if(r-mid==tr[RR].ret)
     38         tr[n].rr+=tr[LL].rr;
     39     } 
     40 }
     41 void built(int l,int r,int n){
     42     lazy[n]=-1;
     43     chan[n]=0;
     44     if(l==r)
     45     {
     46         tr[n].l=tr[n].r=tr[n].res=tr[n].num=a[l];
     47         tr[n].ret=tr[n].ll=tr[n].rr=!a[l];
     48         return;
     49     }
     50     built(lson);
     51     built(rson);
     52     up(l,r,n);
     53 }
     54 void pushdown(int l,int r,int n){
     55     if(lazy[n]!=-1)
     56     {
     57         chan[LL]=chan[RR]=0;
     58         tr[LL].num=tr[LL].l=tr[LL].r=tr[LL].res=(mid-l+1)*lazy[n];
     59         tr[LL].ll=tr[LL].rr=tr[LL].ret=(mid-l+1)*(!lazy[n]);
     60         tr[RR].num=tr[RR].l=tr[RR].r=tr[RR].res=(r-mid)*lazy[n];
     61         tr[RR].ll=tr[RR].rr=tr[RR].ret=(r-mid)*(!lazy[n]);
     62         lazy[LL]=lazy[RR]=lazy[n];
     63         lazy[n]=-1;
     64     }
     65     if(chan[n])
     66     {
     67         chan[LL]^=1;
     68         chan[RR]^=1;
     69         tr[LL].num=mid-l+1-tr[LL].num;
     70         tr[RR].num=r-mid-tr[RR].num;
     71         swap(tr[LL].res,tr[LL].ret);
     72         swap(tr[LL].ll,tr[LL].l);
     73         swap(tr[LL].rr,tr[LL].r);
     74         swap(tr[RR].res,tr[RR].ret);
     75         swap(tr[RR].ll,tr[RR].l);
     76         swap(tr[RR].rr,tr[RR].r);
     77         chan[n]=0; 
     78     }
     79 }
     80 void update(int l,int r,int n,int left,int right,int num){
     81     if(l>=left&&right>=r)
     82     {
     83         lazy[n]=num;
     84         tr[n].num=num*(r-l+1);
     85         chan[n]=0;
     86         tr[n].l=tr[n].r=tr[n].res=(r-l+1)*num;
     87         tr[n].ll=tr[n].rr=tr[n].ret=(r-l+1)*(!num);
     88         return;
     89     }
     90     pushdown(l,r,n);
     91     if(left<=mid)
     92     update(lson,left,right,num);
     93     if(right>mid)
     94     update(rson,left,right,num);
     95     up(l,r,n);
     96 }
     97 void change(int l,int r,int n,int left,int right){
     98     if(l>=left&&right>=r)
     99     {
    100         chan[n]^=1;
    101         tr[n].num=(r-l+1-tr[n].num);
    102         swap(tr[n].res,tr[n].ret);
    103         swap(tr[n].ll,tr[n].l);
    104         swap(tr[n].rr,tr[n].r);
    105         return;
    106     }
    107     pushdown(l,r,n);
    108     if(left<=mid)
    109     change(lson,left,right);
    110     if(right>mid)
    111     change(rson,left,right);
    112     up(l,r,n);
    113 }
    114 int out1(int l,int r,int n,int left,int right){
    115     if(l>=left&&right>=r)
    116     return tr[n].num;
    117     pushdown(l,r,n);
    118     int res=0;
    119     if(left<=mid)
    120     res+=out1(lson,left,right);
    121     if(right>mid)
    122     res+=out1(rson,left,right);
    123     return res;
    124 }
    125 int out2(int l,int r,int n,int left,int right){
    126     if(l>=left&&right>=r)
    127     return tr[n].res;
    128     pushdown(l,r,n);
    129     int res=0;
    130     if(left<=mid)
    131     res=max(res,out2(lson,left,right));
    132     if(right>mid)
    133     res=max(res,out2(rson,left,right));
    134     if(tr[LL].r&&tr[RR].l&&mid>=left&&mid<right)
    135     res=max(res,min(tr[LL].r,mid-left+1)+min(tr[RR].l,right-mid));
    136     return res;
    137 }
    138 int main(){
    139     int t;
    140     scanf("%d",&t);
    141     while(t--)
    142     {
    143         int n,m;
    144         scanf("%d%d",&n,&m);
    145         for(int i=1;i<=n;i++)
    146             scanf("%d",&a[i]);
    147         built(1,n,1);
    148         for(int i=1;i<=m;i++)
    149         {
    150             
    151             int x,y,z;
    152             scanf("%d%d%d",&x,&y,&z);
    153             y++;
    154             z++;
    155             if(x==0)
    156             update(1,n,1,y,z,0);
    157             else
    158             if(x==1)
    159             update(1,n,1,y,z,1);
    160             else
    161             if(x==2)
    162             change(1,n,1,y,z);
    163             if(x==3)
    164             printf("%d
    ",out1(1,n,1,y,z));
    165             else
    166                if(x==4)
    167             printf("%d
    ",out2(1,n,1,y,z));
    168         }
    169     }
    170     return 0;
    171 }
  • 相关阅读:
    Spring Boot
    java 解析命令行参数
    idea 打包java程序
    Dynomite 安装配置
    python 装饰器
    IntelliJ IDEA教程
    ubuntu14.04 rabbitmq安装与使用 --修改RabbitMQ数据存储位置
    ribbbitMq 教程,详细
    spring 的 切片Aspect 最常用记录方法执行时间
    Spring-data-jpa 常用的时间注解
  • 原文地址:https://www.cnblogs.com/julyc/p/6180623.html
Copyright © 2011-2022 走看看