zoukankan      html  css  js  c++  java
  • BZOJ 4592 SHOI2015 脑洞治疗仪 线段树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4592

    题意概述:
    需要维护一个01序列A,一开始A全部都是1。支持如下操作:
      1.将区间[l,r]变成0。
      2.将区间[l0,r0]变成0,用其中原来1的个数去填补[l1,r1]中的0,当1的数量过多的时候剩余的1会被丢弃;当1的数量不足的时候从左到右依次填充0。
      3.询问区间[l,r]中最长的0串长度。
    N,M<=200000.

    我就直接把考试的时候写的东西弄上来了:

      首先建立一颗序列线段树,维护01序列,支持求和操作,同时维护最长序列。

      对于1操作,直接区间赋值为0。

      对于2操作,首先对[l0,r0]对1求和,记为x,然后赋值为0。然后在区间[l1,r1]中找到第一个0数量大于等于x的位置(实在没有就是r1),然后区间赋值。这一步可以用前缀和的思想,先求[1,l1-1](注意先对[l0,r0]操作)中的0数量y,然后就可以在线段树里直接查找第x+y个0的位置,最后的结果和r1比较,取较小值。

      对于3操作,首先在线段树中维护区间左起最长、右起最长、区间最长的0串长度,查询的时候:要查询的区间完全在左半边或者右半边,直接递归处理;当查询区间跨越当前区间的中点,左右区间右起最长,左起最长各自与查询长度取min相加作为一个答案,递归到左右区间,三个答案取最大值;询问区间包含当前区间,直接返回区间最长0串长度(实际上处理的思路就是分治,跨越中间的,左边的,右边的)。

      于是一通维护下来相当于要维护的东西有:1数量之和,0数量之和,0区间最长串三件套。

      时间复杂度O(MlogN)

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<queue>
      8 #include<set>
      9 #include<map>
     10 #include<vector>
     11 #include<cctype>
     12 using namespace std;
     13 
     14 int N,M;
     15 struct segment_tree{
     16     static const int maxn=400005;
     17     int rt,np,lc[maxn],rc[maxn],s0[maxn],s1[maxn],ml[maxn],mr[maxn],mm[maxn],flag[maxn];
     18     segment_tree(){ rt=np=0; }
     19     void pushup(int now,int L,int R){
     20         int m=L+R>>1;
     21         s0[now]=s0[lc[now]]+s0[rc[now]];
     22         s1[now]=s1[lc[now]]+s1[rc[now]];
     23         ml[now]=max(ml[lc[now]],ml[lc[now]]==m-L+1?ml[lc[now]]+ml[rc[now]]:0);
     24         mr[now]=max(mr[rc[now]],mr[rc[now]]==R-m?mr[rc[now]]+mr[lc[now]]:0);
     25         mm[now]=max(mr[lc[now]]+ml[rc[now]],max(mm[lc[now]],mm[rc[now]]));
     26     }
     27     void pushdown(int now,int L,int R){
     28         if(flag[now]==-1) return;
     29         int m=L+R>>1;
     30         if(flag[now]==0){
     31             ml[lc[now]]=mr[lc[now]]=mm[lc[now]]=m-L+1;
     32             s0[lc[now]]=m-L+1,s1[lc[now]]=0,flag[lc[now]]=0;
     33             ml[rc[now]]=mr[rc[now]]=mm[rc[now]]=R-m;
     34             s0[rc[now]]=R-m,s1[rc[now]]=0,flag[rc[now]]=0;
     35         }
     36         else{
     37             ml[lc[now]]=mr[lc[now]]=mm[lc[now]]=0;
     38             s0[lc[now]]=0,s1[lc[now]]=m-L+1,flag[lc[now]]=1;
     39             ml[rc[now]]=mr[rc[now]]=mm[rc[now]]=0;
     40             s0[rc[now]]=0,s1[rc[now]]=R-m,flag[rc[now]]=1;
     41         }
     42         flag[now]=-1;
     43     }
     44     void build(int &now,int L,int R){
     45         now=++np;
     46         lc[now]=rc[now]=0,s0[now]=ml[now]=mr[now]=mm[now]=0,s1[now]=R-L+1,flag[now]=-1;
     47         if(L==R) return;
     48         int m=L+R>>1;
     49         build(lc[now],L,m); build(rc[now],m+1,R);
     50     }
     51     void update(int now,int L,int R,int A,int B,int v){
     52         if(A<=L&&R<=B){
     53             if(v==0){
     54                 ml[now]=mr[now]=mm[now]=R-L+1;
     55                 s0[now]=R-L+1,s1[now]=0,flag[now]=0;
     56             }
     57             else{
     58                 ml[now]=mr[now]=mm[now]=0;
     59                 s0[now]=0,s1[now]=R-L+1,flag[now]=1;
     60             }
     61             return;
     62         }
     63         pushdown(now,L,R);
     64         int m=L+R>>1;
     65         if(B<=m) update(lc[now],L,m,A,B,v);
     66         else if(A>m) update(rc[now],m+1,R,A,B,v);
     67         else update(lc[now],L,m,A,B,v),update(rc[now],m+1,R,A,B,v);
     68         pushup(now,L,R);
     69     }
     70     int query_s(int now,int L,int R,int A,int B,int v){
     71         if(A<=L&&R<=B) return v?s1[now]:s0[now];
     72         pushdown(now,L,R);
     73         int m=L+R>>1;
     74         if(B<=m) return query_s(lc[now],L,m,A,B,v);
     75         if(A>m) return query_s(rc[now],m+1,R,A,B,v);
     76         return query_s(lc[now],L,m,A,B,v)+query_s(rc[now],m+1,R,A,B,v);
     77     }
     78     int query_p(int now,int L,int R,int k){
     79         if(L==R) return L;
     80         pushdown(now,L,R);
     81         int m=L+R>>1;
     82         if(k<=s0[lc[now]]) return query_p(lc[now],L,m,k);
     83         return query_p(rc[now],m+1,R,k-s0[lc[now]]);
     84     }
     85     int query_mm(int now,int L,int R,int A,int B){
     86         if(A<=L&&R<=B) return mm[now];
     87         pushdown(now,L,R);
     88         int m=L+R>>1;
     89         if(B<=m) return query_mm(lc[now],L,m,A,B);
     90         if(A>m) return query_mm(rc[now],m+1,R,A,B);
     91         int re=min(m-A+1,mr[lc[now]])+min(B-m,ml[rc[now]]);
     92         return max(re,max(query_mm(lc[now],L,m,A,m),query_mm(rc[now],m+1,R,m+1,B)));
     93     }
     94 }st;
     95 
     96 void work()
     97 {
     98     scanf("%d%d",&N,&M);
     99     st.build(st.rt,1,N);
    100     int op,l0,r0,l1,r1,x,y,p;
    101     for(int i=1;i<=M;i++){
    102         scanf("%d",&op);
    103         if(op==0){
    104             scanf("%d%d",&l0,%r0);
    105             st.update(st.rt,1,N,l0,r0,0);
    106         }
    107         else if(op==1){
    108             scanf("%d%d%d%d",&l0,&r0,&l1,&r1);
    109             x=st.query_s(st.rt,1,N,l0,r0,1);
    110             if(!x) continue;
    111             st.update(st.rt,1,N,l0,r0,0);
    112             y=l1==1?0:st.query_s(st.rt,1,N,1,l1-1,0);
    113             p=min(r1,st.query_p(st.rt,1,N,y+x));
    114             st.update(st.rt,1,N,l1,p,1);
    115         }
    116         else if(op==2){
    117             scanf("%d%d",&l0,&r0);
    118             printf("%d
    ",st.query_mm(st.rt,1,N,l0,r0));
    119         }
    120     }
    121 }
    122 int main()
    123 {
    124     work();
    125     return 0;
    126 }
    View Code
  • 相关阅读:
    List<Map>遍历相加
    jqgrid属性
    idea Could not autowire. No beans of 'xxxx' type found
    【笔记】抓取百度贴吧
    python url中文转码
    python lxml 库
    Python 基础 (笔记)
    HTML 背景
    HTML Iframe
    HTML 响应式 Web 设计
  • 原文地址:https://www.cnblogs.com/KKKorange/p/8630993.html
Copyright © 2011-2022 走看看