• BZOJ3064 Tyvj 1518 CPU监控 线段树


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ3064


    题意概括

      一个序列,要你支持以下操作:

      1. 区间询问最大值

      2. 区间询问历史最大值

      3. 区间加某一个值

      4. 区间赋值

      序列长度<=100000, 操作数<=100000


    题解

    http://blog.csdn.net/vmurder/article/details/43271091

    为了一个傻逼错误找了2个小时的我,实在不想写题解了。请您看上面那个链接 的……


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    using namespace std;
    typedef long long LL;
    const int N=100005;
    const int Inf=2147483647;
    struct Tree{
    	int hMax,Max,hadd,add,hco,co;
    }t[N*4];
    int n,m,v[N];
    void p(int &a,int b){
    	a=max(a,b);
    }
    void pushup(int rt){
    	int ls=rt<<1,rs=ls|1;
    	t[rt].Max=max(t[ls].Max,t[rs].Max);
    	p(t[rt].hMax,max(t[ls].hMax,t[rs].hMax));
    }
    void build(int rt,int L,int R){
    	t[rt].add=t[rt].hadd=0,t[rt].hco=t[rt].co=-Inf;
    	if (L==R){
    		t[rt].Max=t[rt].hMax=v[L];
    		return;
    	}
    	int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
    	build(ls,L,mid);
    	build(rs,mid+1,R);
    	pushup(rt);
    }
    void now_add(int rt,int v){
    	if (t[rt].co>-Inf)
    		p(t[rt].hco,t[rt].co+=v);
    	else
    		p(t[rt].hadd,t[rt].add+=v);
    	p(t[rt].hMax,t[rt].Max+=v);
    }
    void now_cover(int rt,int v){
    	p(t[rt].hMax,t[rt].Max=v);
    	p(t[rt].hco,t[rt].co=v);
    	t[rt].add=0;
    }
    void his_add(int rt,int v){
    	p(t[rt].hMax,t[rt].Max+v);
    	if (t[rt].co>-Inf)
    		p(t[rt].hco,t[rt].co+v);
    	else
    		p(t[rt].hadd,t[rt].add+v);
    }
    void his_cover(int rt,int v){
    	p(t[rt].hMax,v);
    	p(t[rt].hco,v);
    }
    void pushdown(int rt){
    	int ls=rt<<1,rs=ls|1;
    	int &add=t[rt].add,&hadd=t[rt].hadd,&co=t[rt].co,&hco=t[rt].hco;
    	if (hadd){
    		his_add(ls,hadd);
    		his_add(rs,hadd);
    		hadd=0;
    	}
    	if (hco>-Inf){
    		his_cover(ls,hco);
    		his_cover(rs,hco);
    		hco=-Inf;
    	}
    	if (add){
    		now_add(ls,add);
    		now_add(rs,add);
    		add=0;
    	}
    	if (co>-Inf){
    		now_cover(ls,co);
    		now_cover(rs,co);
    		co=-Inf;
    	}
    }
    void update(int rt,int le,int ri,int xle,int xri,int v,int op){
    	if (le>xri||ri<xle)
    		return;
    	if (xle<=le&&ri<=xri){
    		if (!op)
    			now_add(rt,v);
    		else
    			now_cover(rt,v);
    		return;
    	}
    	pushdown(rt);
    	int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
    	update(ls,le,mid,xle,xri,v,op);
    	update(rs,mid+1,ri,xle,xri,v,op);
    	pushup(rt);
    }
    int query(int rt,int le,int ri,int xle,int xri,int op){
    	if (le>xri||ri<xle)
    		return -Inf;
    	if (xle<=le&&ri<=xri)
    		return op?t[rt].hMax:t[rt].Max;
    	pushdown(rt);
    	int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
    	return max(query(ls,le,mid,xle,xri,op),query(rs,mid+1,ri,xle,xri,op));
    }
    int main(){
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    		scanf("%d",&v[i]);
    	build(1,1,n);
    	scanf("%d",&m);
    	for (int i=1;i<=m;i++){
    		char op[5];
    		int x,y,z;
    		scanf("%s",op);
    		if (op[0]=='Q'){
    			scanf("%d%d",&x,&y);
    			printf("%d
    ",query(1,1,n,x,y,0));
    		}
    		if (op[0]=='A'){
    			scanf("%d%d",&x,&y);
    			printf("%d
    ",query(1,1,n,x,y,1));
    		}
    		if (op[0]=='P'){
    			scanf("%d%d%d",&x,&y,&z);
    			update(1,1,n,x,y,z,0);
    		}
    		if (op[0]=='C'){
    			scanf("%d%d%d",&x,&y,&z);
    			update(1,1,n,x,y,z,1);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    编译安装glibc
    Android SDK下载
    Ubuntu下Android编译环境的配置
    ubuntu常用命令
    硬盘概念解析
    ubuntu官方源列表网址
    Win7系统下利用U盘安装Ubuntu14.04麒麟版
    jdk5下载链接
    vim跳到文件头和文末结尾
    vim 全局替换命令
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ3064.html
Copyright © 2020-2023  润新知