zoukankan      html  css  js  c++  java
  • [uoj164]V

    记$a_{i}$为当前第$i$个水箱的电流,$b_{i}$为$a_{i}$的历史最大值

    不难发现,问题即要支持:对$a_{i}$区间覆盖和区间加(并对0取$max$);查询某个$a_{i}$和$b_{i}$

    整体思路类似于bzoj3064,仍维护$max a,b$​和操作序列,操作执行方式即令
    $$
    egin{cases}max a=x,max b=max(max b,max a)&(覆盖操作)\max a=max(max a+x,0),max b=max(max b,max a)&(加操作)end{cases}
    $$
    维护的信息也是类似地,只需要重新定义"和",并将第一个信息的两个值均用与$max a$有关的函数形式存储,那么同样也可以合并

    考虑函数的形式,对两者分别讨论:

    1.第一个值的函数仅取决于最小前缀和和整个序列的和,并且可以合并

    2.第二个值的函数仅取决于最大前缀和、最大子段和,并且需要再维护最大后缀和(即整个序列的和-最小前缀和)来支持合并

    具体合并方式可以根据定义得到或参考代码,这里省略

    (不难发现也是可以支持区间查询$a_{i}$和$b_{i}$最大值的)

    时间复杂度为$o(mlog n)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 500005
     4 #define ll long long
     5 #define L (k<<1)
     6 #define R (L+1)
     7 #define mid (l+r>>1)
     8 struct Data{
     9     ll s1,mx1,mn1,mx,p,s2,mx2,Mx;
    10 }tag[N<<2];
    11 int n,m,p,x,y,z,leaf[N<<2];
    12 ll a[N<<2],b[N<<2];
    13 void upd(int k,Data x){
    14     if (leaf[k]==1){
    15         b[k]=max(b[k],max(max(a[k]+x.mx1,x.mx),x.Mx));
    16         if (x.p)a[k]=x.s2;
    17         else a[k]=max(a[k],-x.mn1)+x.s1;
    18     }
    19     if (tag[k].p){
    20         tag[k].mx2=max(tag[k].mx2,max(tag[k].s2+x.mx1,x.mx));
    21         tag[k].Mx=max(tag[k].Mx,max(tag[k].s2+x.mx1,x.mx));
    22         tag[k].s2=max(tag[k].s2,-x.mn1)+x.s1;
    23     }
    24     else{
    25         tag[k].mx=max(tag[k].mx,max(tag[k].s1-tag[k].mn1+x.mx1,x.mx));
    26         tag[k].mn1=min(tag[k].mn1,tag[k].s1+x.mn1);
    27         tag[k].mx1=max(tag[k].mx1,tag[k].s1+x.mx1);
    28         tag[k].s1+=x.s1;
    29     }
    30     if (x.p){
    31         tag[k].p=1,tag[k].s2=x.s2,tag[k].mx2=x.mx2;
    32         tag[k].Mx=max(tag[k].Mx,x.Mx);
    33     }
    34 }
    35 void down(int k){
    36     upd(L,tag[k]);
    37     upd(R,tag[k]);
    38     tag[k]=Data{0,0,0,0,0,0,(ll)-1e18,(ll)-1e18};
    39 }
    40 void build(int k,int l,int r){
    41     leaf[k]=0;
    42     tag[k]=Data{0,0,0,0,0,0,(ll)-1e18,(ll)-1e18};
    43     if (l==r){
    44         leaf[k]=1;
    45         scanf("%lld",&a[k]);
    46         b[k]=a[k];
    47         return;
    48     } 
    49     build(L,l,mid);
    50     build(R,mid+1,r);
    51 }
    52 void update(int k,int l,int r,int x,int y,Data z){
    53     if ((l>y)||(x>r))return;
    54     if ((x<=l)&&(r<=y)){
    55         upd(k,z);
    56         return;
    57     }
    58     down(k);
    59     update(L,l,mid,x,y,z);
    60     update(R,mid+1,r,x,y,z);
    61 }
    62 ll query_a(int k,int l,int r,int x){
    63     if (l==r)return a[k];
    64     down(k);
    65     if (x<=mid)return query_a(L,l,mid,x);
    66     return query_a(R,mid+1,r,x);
    67 }
    68 ll query_b(int k,int l,int r,int x){
    69     if (l==r)return b[k];
    70     down(k);
    71     if (x<=mid)return query_b(L,l,mid,x);
    72     return query_b(R,mid+1,r,x);
    73 }
    74 int main(){
    75     scanf("%d%d",&n,&m);
    76     build(1,1,n);
    77     for(int i=1;i<=m;i++){
    78         scanf("%d%d",&p,&x);
    79         if (p==1){
    80             scanf("%d%d",&y,&z);
    81             update(1,1,n,x,y,Data{z,z,0,z,0,0,0,(ll)-1e18});
    82         }
    83         if (p==2){
    84             scanf("%d%d",&y,&z);
    85             update(1,1,n,x,y,Data{-z,0,-z,0,0,0,0,(ll)-1e18});
    86         }
    87         if (p==3){
    88             scanf("%d%d",&y,&z);
    89             update(1,1,n,x,y,Data{0,0,0,0,1,z,z,z});
    90         }
    91         if (p==4)printf("%lld
    ",query_a(1,1,n,x));
    92         if (p==5)printf("%lld
    ",query_b(1,1,n,x));
    93     }
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    JQuery:自动触发事件
    SQL Server 取日期时间部分
    使用IIS 7.0 / 7.5 时配置HttpModules需要注意
    Winform:中直接打开指定文件
    jQuery 时间获取扩展
    喵星史话(一)——猫的起源
    2013年的环法
    ie8下奇怪的问题:float:left之后,右侧的div会影响左侧
    虚假IP和DNS污染
    android中setBackgroundResource和setBackgroundDrawable和用法
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15352524.html
Copyright © 2011-2022 走看看