zoukankan      html  css  js  c++  java
  • BZOJ 3064 Tyvj 1518 CPU监控

    题解:历史最值线段树

    参见吉司机的论文

    还是不熟,自己打打不出来

    维护当前和历史两套标记,最大值,加法标记,减法标记

    每到一个节点先pushdown(不知道为什么)

    正确性不是很理解QWQ

    还是自己太弱了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=100009;
    typedef long long Lint;
    const Lint inf=1000000000000000;
    
    int n,m;
    Lint a[maxn];
    
    struct SegmentTree{
    	int l,r;
    	Lint mx[2],tag[2],st[2];
    }tree[maxn<<3];
    
    void pushup(int now){
    	tree[now].mx[0]=max(tree[now<<1].mx[0],tree[now<<1|1].mx[0]);
    	tree[now].mx[1]=max(tree[now<<1].mx[1],tree[now<<1|1].mx[1]);
    }
    void pushdown(int now){
    	int son;
    	for(int i=0;i<=1;++i){
    		son=now<<1|i;
    		tree[son].mx[0]=max(tree[son].mx[0],max(tree[now].st[0],tree[son].mx[1]+tree[now].tag[0]));
    		if(tree[son].st[1]==-inf){
    			tree[son].tag[0]=max(tree[son].tag[0],tree[son].tag[1]+tree[now].tag[0]);
    		}else{
    			tree[son].st[0]=max(tree[son].st[0],tree[son].st[1]+tree[now].tag[0]);
    		}
    		if(tree[now].tag[1]){
    			if(tree[son].st[1]!=-inf)tree[son].st[1]+=tree[now].tag[1];
    			else tree[son].tag[1]+=tree[now].tag[1];
    			tree[son].mx[1]+=tree[now].tag[1];
    		}
    		if(tree[now].st[1]!=-inf){
    			tree[son].st[1]=tree[son].mx[1]=tree[now].st[1];
    			tree[son].tag[1]=0;
    		}
    		tree[son].st[0]=max(tree[son].st[0],max(tree[son].st[1],tree[now].st[0]));
    		tree[son].tag[0]=max(tree[son].tag[0],tree[son].tag[1]);
    	}
    	tree[now].tag[0]=tree[now].tag[1]=0;
    	tree[now].st[0]=tree[now].st[1]=-inf;
    }
    
    void BuildTree(int now,int l,int r){
    	tree[now].l=l;tree[now].r=r;
    	tree[now].tag[0]=tree[now].tag[1]=0;
    	tree[now].st[0]=tree[now].st[1]=-inf;
    	if(l==r){
    		tree[now].mx[0]=tree[now].mx[1]=a[l];
    		return;
    	}
    	int mid=(l+r)>>1;
    	BuildTree(now<<1,l,mid);
    	BuildTree(now<<1|1,mid+1,r);
    	pushup(now);
    }
    
    void Updatasec(int now,int ll,int rr,Lint x,int opty){
    	if(tree[now].l!=tree[now].r)pushdown(now);
    	if(tree[now].l>=ll&&tree[now].r<=rr){
    		if(opty==0){
    			tree[now].mx[1]+=x;tree[now].tag[1]+=x;tree[now].tag[0]=x;
    		}else{
    			tree[now].st[1]=tree[now].st[0]=tree[now].mx[1]=x;
    		}
    		tree[now].mx[0]=max(tree[now].mx[0],tree[now].mx[1]);
    		return;
    	}
    	int mid=(tree[now].l+tree[now].r)>>1;
    	if(ll<=mid)Updatasec(now<<1,ll,rr,x,opty);
    	if(rr>mid)Updatasec(now<<1|1,ll,rr,x,opty);
    	pushup(now);
    }
    
    Lint Querymax(int now,int ll,int rr,int opty){
    	if(tree[now].l!=tree[now].r)pushdown(now);
    	if(tree[now].l>=ll&&tree[now].r<=rr){
    		return tree[now].mx[opty];
    	}
    	Lint ans=-inf;
    	int mid=(tree[now].l+tree[now].r)>>1;
    	if(ll<=mid)ans=max(ans,Querymax(now<<1,ll,rr,opty));
    	if(rr>mid)ans=max(ans,Querymax(now<<1|1,ll,rr,opty));
    	return ans;
    }
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
    	BuildTree(1,1,n);
    	scanf("%d",&m);
    	while(m--){
    		char opty=getchar();
    		while(opty<'A'||opty>'Z')opty=getchar();
    		int l,r,x;
    		scanf("%d%d",&l,&r);
    		if(opty=='Q')printf("%lld
    ",Querymax(1,l,r,1));
    		if(opty=='A')printf("%lld
    ",Querymax(1,l,r,0));
    		if(opty=='P'){
    			scanf("%d",&x);Updatasec(1,l,r,x,0);
    		}
    		if(opty=='C'){
    			scanf("%d",&x);Updatasec(1,l,r,x,1);
    		}
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    ZSSR
    分享mysql db 分区分表的shell
    oracle12c的CDB与PDB
    nodejs连接redis
    webservice 访问 网络共享文件夹 权限问题的解决方案
    闭包后感
    简单记录几个wpf学习上的问题[ObservableQueue]
    源码分析之Iterable&Collection(一)
    数据结构之树(三)
    数据结构之哈希表(二)
  • 原文地址:https://www.cnblogs.com/zzyer/p/8456403.html
Copyright © 2011-2022 走看看