zoukankan      html  css  js  c++  java
  • [bzoj4695]最假女选手

    整体思路类似于hdu5306,在线段树上维护区间内最大值及个数、严格次大值、最小值及个数、严格次小值和区间和,即可支持$o(log n)$查询

    修改时,区间加直接维护即可,区间取$min$的做法与该题相同——

    修改时,搜索至完全覆盖的区间后再分类讨论:

    1.若修改值大于严格次大值,可以打上懒标记并维护上述信息

    2.若修改值不超过严格次大值,继续递归下去

    区间取$max$和取$min$类似,利用最小值的信息即可(另外,注意当区间内权值种类数$le 2$时还要修改另一边的值和标记)

    考虑这样的修改复杂度,定义势能为线段树上与父亲最大值不同的节点树深度和,为了方便不妨仅考虑区间加和区间取$min$这两种操作(区间取$max$是类似的),并分别讨论:

    1.对于区间加,至多使得被访问的节点计入势能,即均摊复杂度为$o(log^{2}n)$

    2.对于区间取$min$,显然这不会使得任何节点对势能贡献增加,下面考虑对势能贡献减少的节点(即操作前与父亲最大值不同且操作后相同),具体分析如下:

    取出所有访问过的位置(不包括打标记的位置),构成一棵二叉树

    考虑这棵二叉树的叶子,必然有其不是原线段树的叶子且其两个儿子都被打上标记

    根据递归过程,两个儿子的次大值均$<x$,而父亲的次大值$ge x$,因此父亲的最大值和次大值分别为某个儿子的最大值,即恰有一个儿子初始对势能有贡献(即为次大值的)

    注意到父亲的次大值$ge x$,因此父亲和该儿子操作后最大值均为$x$,即其对势能贡献减少,且根据定义减小的是其深度,那么不难得到均摊复杂度为$o(1)$

    势能范围为$[0,nlog n]$,因此时间复杂度为$o(nlog n+mlog^{2}n)$,可以通过

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 500005
      4 #define oo 0x3f3f3f3f
      5 #define ll long long
      6 #define L (k<<1)
      7 #define R (L+1)
      8 #define mid (l+r>>1)
      9 int t,n,m,p,x,y,z,a[N],len[N<<2],mx[N<<2],mn[N<<2],cnt_mx[N<<2],cnt_mn[N<<2],cmx[N<<2],cmn[N<<2],tag[N<<2],tag_mx[N<<2],tag_mn[N<<2];
     10 ll sum[N<<2];
     11 void upd(int k,int x){
     12     tag[k]+=x,mx[k]+=x,mn[k]+=x,sum[k]+=(ll)len[k]*x;
     13     if (cmx[k]!=-oo)cmx[k]+=x;
     14     if (cmn[k]!=oo)cmn[k]+=x;
     15     if (tag_mx[k]!=oo)tag_mx[k]+=x;
     16     if (tag_mn[k]!=oo)tag_mn[k]+=x;
     17 }
     18 void upd_mx(int k,int x){
     19     if (mx[k]<=x)return;
     20     sum[k]+=(ll)cnt_mx[k]*(x-mx[k]);
     21     if (mn[k]==mx[k]){
     22         mn[k]=x;
     23         if (tag_mn[k]!=oo)tag_mn[k]=x;
     24     }
     25     if (cmn[k]==mx[k])cmn[k]=x;
     26     tag_mx[k]=mx[k]=x;
     27 }
     28 void upd_mn(int k,int x){
     29     if (mn[k]>=x)return;
     30     sum[k]+=(ll)cnt_mn[k]*(x-mn[k]);
     31     if (mx[k]==mn[k]){
     32         mx[k]=x;
     33         if (tag_mx[k]!=oo)tag_mx[k]=x;
     34     }
     35     if (cmx[k]==mn[k])cmx[k]=x;
     36     tag_mn[k]=mn[k]=x;
     37 }
     38 void up(int k){
     39     mx[k]=max(mx[L],mx[R]),mn[k]=min(mn[L],mn[R]),sum[k]=sum[L]+sum[R];
     40     cnt_mx[k]=cnt_mn[k]=0,cmx[k]=max(cmx[L],cmx[R]),cmn[k]=min(cmn[L],cmn[R]);
     41     if (mx[k]==mx[L])cnt_mx[k]+=cnt_mx[L];
     42     else cmx[k]=max(cmx[k],mx[L]);
     43     if (mx[k]==mx[R])cnt_mx[k]+=cnt_mx[R];
     44     else cmx[k]=max(cmx[k],mx[R]);
     45     if (mn[k]==mn[L])cnt_mn[k]+=cnt_mn[L];
     46     else cmn[k]=min(cmn[k],mn[L]);
     47     if (mn[k]==mn[R])cnt_mn[k]+=cnt_mn[R];
     48     else cmn[k]=min(cmn[k],mn[R]);
     49 }
     50 void down(int k){
     51     if (tag[k]){
     52         upd(L,tag[k]);
     53         upd(R,tag[k]);
     54         tag[k]=0;
     55     }
     56     if (tag_mx[k]!=oo){
     57         upd_mx(L,tag_mx[k]);
     58         upd_mx(R,tag_mx[k]);
     59         tag_mx[k]=oo;
     60     }
     61     if (tag_mn[k]!=oo){
     62         upd_mn(L,tag_mn[k]);
     63         upd_mn(R,tag_mn[k]);
     64         tag_mn[k]=oo;
     65     }
     66 }
     67 void build(int k,int l,int r){
     68     len[k]=r-l+1,tag[k]=0,tag_mx[k]=tag_mn[k]=oo;
     69     if (l==r){
     70         mx[k]=mn[k]=sum[k]=a[l];
     71         cnt_mx[k]=cnt_mn[k]=1,cmx[k]=-oo,cmn[k]=oo;
     72         return;
     73     }
     74     build(L,l,mid);
     75     build(R,mid+1,r);
     76     up(k);
     77 }
     78 void update_add(int k,int l,int r,int x,int y,int z){
     79     if ((l>y)||(x>r))return;
     80     if ((x<=l)&&(r<=y)){
     81         upd(k,z);
     82         return;
     83     }
     84     down(k);
     85     update_add(L,l,mid,x,y,z);
     86     update_add(R,mid+1,r,x,y,z);
     87     up(k);
     88 }
     89 void update_max(int k,int l,int r,int x,int y,int z){
     90     if ((l>y)||(x>r))return;
     91     if ((x<=l)&&(r<=y)&&(cmn[k]>z)){
     92         upd_mn(k,z);
     93         return;
     94     }
     95     down(k);
     96     update_max(L,l,mid,x,y,z);
     97     update_max(R,mid+1,r,x,y,z);
     98     up(k);
     99 }
    100 void update_min(int k,int l,int r,int x,int y,int z){
    101     if ((l>y)||(x>r))return;
    102     if ((x<=l)&&(r<=y)&&(cmx[k]<z)){
    103         upd_mx(k,z);
    104         return;
    105     }
    106     down(k);
    107     update_min(L,l,mid,x,y,z);
    108     update_min(R,mid+1,r,x,y,z);
    109     up(k);
    110 }
    111 int query_max(int k,int l,int r,int x,int y){
    112     if ((l>y)||(x>r))return -oo;
    113     if ((x<=l)&&(r<=y))return mx[k];
    114     down(k);
    115     return max(query_max(L,l,mid,x,y),query_max(R,mid+1,r,x,y));
    116 }
    117 int query_min(int k,int l,int r,int x,int y){
    118     if ((l>y)||(x>r))return oo;
    119     if ((x<=l)&&(r<=y))return mn[k];
    120     down(k);
    121     return min(query_min(L,l,mid,x,y),query_min(R,mid+1,r,x,y));
    122 }
    123 ll query_sum(int k,int l,int r,int x,int y){
    124     if ((l>y)||(x>r))return 0;
    125     if ((x<=l)&&(r<=y))return sum[k];
    126     down(k);
    127     return query_sum(L,l,mid,x,y)+query_sum(R,mid+1,r,x,y);
    128 }
    129 int main(){
    130     scanf("%d",&n);
    131     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    132     build(1,1,n);
    133     scanf("%d",&m);
    134     for(int i=1;i<=m;i++){
    135         scanf("%d%d%d",&p,&x,&y);
    136         if (p==1){
    137             scanf("%d",&z);
    138             update_add(1,1,n,x,y,z);
    139         }
    140         if (p==2){
    141             scanf("%d",&z);
    142             update_max(1,1,n,x,y,z);
    143         }
    144         if (p==3){
    145             scanf("%d",&z);
    146             update_min(1,1,n,x,y,z);
    147         }
    148         if (p==4)printf("%lld
    ",query_sum(1,1,n,x,y));
    149         if (p==5)printf("%d
    ",query_max(1,1,n,x,y));
    150         if (p==6)printf("%d
    ",query_min(1,1,n,x,y));
    151     }
    152     return 0;
    153 } 
    View Code
  • 相关阅读:
    转载 Markdown 写法 直接考代码 反正博客园支持
    最全的ADB命令行大全(转)
    Python 帮你玩微信跳一跳 GitHub Python脚本
    React中setState的怪异行为 ——setState没有即时生效
    详解es6中Proxy代理对象的作用
    react-router和react-router-dom的区别
    webpack4 Cannot find module '@babel/core'
    vue-devtools的安装与使用
    Vuex的mapGetters方法使用报错
    vuex直接修改state 与 用commit提交mutation来修改state的差异
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15348256.html
Copyright © 2011-2022 走看看