zoukankan      html  css  js  c++  java
  • BZOJ3064: Tyvj 1518 CPU监控

    n<=100000的数列支持以下操作:一、区间加;二、区间赋值;三、查区间最大;四、查区间历史版本最大。

    恶心死我了。。可能很水,但我调了半天。

    错误!调了两天。

    这里有一个棘手问题:历史版本。

    首先不看赋值操作。记俩标记——区间加add和区间历史加标记pre。其中后者的含义是“从上一次这个区间标记下传到现在,区间加(前者)标记的最大值”。这样,比如某点i的标记下传给儿子x,标记如此叠加:$pre_x>?=pre_i+add_x$,$add_x+=add_i$,同时更新区间历史版本最大值:$his_x>?=Max_x+pre_x-add_x$。

    然后加入赋值操作。可以发现一个区间在标记下传前只有两个阶段:一开始只有加标记,后来只有赋值标记:打上赋值标记后,如果该区间还要加,相当于更新赋值标记。因此,分两种历史标记来搞,一个记第一阶段的$add$的最大值,一个记第二阶段$be$的最大值。下传时注意顺序。

    关键点截图留念:

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<math.h>
      6 //#include<complex>
      7 //#include<ctime>
      8 #include<algorithm>
      9 using namespace std;
     10 
     11 int n,m;
     12 #define maxn 100011
     13 const int inf=0x3f3f3f3f;
     14 int num[maxn];
     15 struct SMT
     16 {
     17     struct Node
     18     {
     19         int ls,rs;
     20         int add,pa,be,pb;
     21         int Max,pmax;
     22     }a[maxn<<1];
     23     int size,root;
     24     SMT() {size=root=0; a[0].Max=a[0].pmax=-inf;}
     25     void up(int x,int L,int R)
     26     {
     27         int &p=a[x].ls,&q=a[x].rs;
     28         a[x].Max=max(a[p].Max,a[q].Max);
     29         a[x].pmax=max(a[p].pmax,a[q].pmax);
     30     }
     31     void addsingle(int x,int L,int R,int v,int pv)
     32     {
     33         if (a[x].be!=-inf)
     34         {besingle(x,L,R,a[x].be+v,a[x].be+pv); return;}
     35         a[x].pa=max(a[x].pa,a[x].add+pv),a[x].add+=v;
     36         a[x].Max+=v; a[x].pmax=max(a[x].pmax,a[x].pa+a[x].Max-a[x].add);
     37     }
     38     void besingle(int x,int L,int R,int v,int pv)
     39     {
     40         a[x].pb=max(a[x].pb,pv); a[x].add=0; a[x].be=v;
     41         a[x].Max=v; a[x].pmax=max(a[x].pmax,a[x].pb);
     42     }
     43     void down(int x,int L,int R)
     44     {
     45         int &p=a[x].ls,&q=a[x].rs,mid=(L+R)>>1;
     46         if (a[x].add || a[x].pa)
     47         addsingle(p,L,mid,a[x].add,a[x].pa),addsingle(q,mid+1,R,a[x].add,a[x].pa),a[x].add=a[x].pa=0;
     48         if (a[x].be!=-inf || a[x].pb!=-inf)
     49         besingle(p,L,mid,a[x].be,a[x].pb),besingle(q,mid+1,R,a[x].be,a[x].pb),a[x].be=a[x].pb=-inf;
     50     }
     51     void build(int &x,int L,int R)
     52     {
     53         x=++size;
     54         a[x].add=a[x].pa=0; a[x].be=a[x].pb=-inf; 
     55         if (L==R) {a[x].ls=a[x].rs=0; a[x].Max=a[x].pmax=num[L];return;}
     56         int mid=(L+R)>>1;
     57         build(a[x].ls,L,mid); build(a[x].rs,mid+1,R); up(x,L,R);
     58     }
     59     void build() {build(root,1,n);}
     60     int ql,qr,v;
     61     void Add(int &x,int L,int R)
     62     {
     63         if (ql<=L && R<=qr) {addsingle(x,L,R,v,v); return;}
     64         down(x,L,R);
     65         int mid=(L+R)>>1;
     66         if (ql<=mid) Add(a[x].ls,L,mid);
     67         if (qr> mid) Add(a[x].rs,mid+1,R);
     68         up(x,L,R);
     69     }
     70     void add(int L,int R,int v)
     71     {
     72         ql=L; qr=R; this->v=v;
     73         Add(root,1,n);
     74     }
     75     void Be(int &x,int L,int R)
     76     {
     77         if (ql<=L && R<=qr) {besingle(x,L,R,v,v); return;}
     78         down(x,L,R);
     79         int mid=(L+R)>>1;
     80         if (ql<=mid) Be(a[x].ls,L,mid);
     81         if (qr> mid) Be(a[x].rs,mid+1,R);
     82         up(x,L,R);
     83     }
     84     void be(int L,int R,int v)
     85     {
     86         ql=L; qr=R; this->v=v;
     87         Be(root,1,n);
     88     }
     89     int Qmax(int &x,int L,int R)
     90     {
     91         if (ql<=L && R<=qr) return a[x].Max;
     92         down(x,L,R);
     93         int mid=(L+R)>>1,ans=-inf;
     94         if (ql<=mid) ans=Qmax(a[x].ls,L,mid);
     95         if (qr> mid) ans=max(ans,Qmax(a[x].rs,mid+1,R));
     96         return ans;
     97     }
     98     int qmax(int L,int R)
     99     {
    100         ql=L; qr=R;
    101         return Qmax(root,1,n);
    102     }
    103     int Qpmax(int &x,int L,int R)
    104     {
    105         if (ql<=L && R<=qr) return a[x].pmax;
    106         down(x,L,R);
    107         int mid=(L+R)>>1,ans=-inf;
    108         if (ql<=mid) ans=Qpmax(a[x].ls,L,mid);
    109         if (qr> mid) ans=max(ans,Qpmax(a[x].rs,mid+1,R));
    110         return ans;
    111     }
    112     int qpmax(int L,int R)
    113     {
    114         ql=L; qr=R;
    115         return Qpmax(root,1,n);
    116     }
    117 }t;
    118 
    119 int main()
    120 {
    121     scanf("%d",&n);
    122     for (int i=1;i<=n;i++) scanf("%d",&num[i]);
    123     t.build();
    124     
    125     scanf("%d",&m);
    126     int x,y,z; char id;
    127     while (m--)
    128     {
    129         while ((id=getchar())<'A' || id>'Z');
    130         if (id=='A') scanf("%d%d",&x,&y),printf("%d
    ",t.qpmax(x,y));
    131         else if (id=='Q') scanf("%d%d",&x,&y),printf("%d
    ",t.qmax(x,y));
    132         else if (id=='P') scanf("%d%d%d",&x,&y,&z),t.add(x,y,z);
    133         else scanf("%d%d%d",&x,&y,&z),t.be(x,y,z);
    134     }
    135     return 0;
    136 }
    View Code
  • 相关阅读:
    终极调试工具EventRecorder使用方法,各种Link通吃
    stm32如何才能正常运行的调试笔记
    自己常用的vscode的插件备忘录
    linux下(lubuntu18.04.4)安装tinycc编译器及运行调试C语言
    虚拟机下的lubuntu14.04磁盘扩展
    使用lubuntu14.04编译ESP8266_NONOS_SDK3.0.0
    c语言中不建议使用的库函数
    RS485, RS422 and RS232连线
    Sql server output 功能介绍
    句子成分:主谓宾等
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8448451.html
Copyright © 2011-2022 走看看