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

    题目链接:CPU监控

      学习一番线段树的历史标记~

      这道题就是区间加法,区间赋值,要询问区间最大值 和 区间历史最大值的最大值。

      然后这种题就是在现有标记的基础上多弄一套标记,维护这个点出现过的最大的标记。然后下传标记的时候注意要先传历史标记再传现在的标记。

      王队告诉我说,关于历史标记,可以理解成每个节点有过很多标记,可以看成每个节点都有一个标记队列。这样的话,现在的标记就是在维护这个队列的最后一个,历史标记就是这个队列的(max)。所以传标记的时候需要先下传历史标记。

      一定要把各种标记想清楚了再写。

      下面贴代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    #define INF (-2147483647)
    #define maxn 100010
    
    using namespace std;
    typedef long long llg;
    
    int n,m,L,R,_nm,_pm,z,_;
    int nmax[maxn<<2],nadd[maxn<<2],ncov[maxn<<2];//现在的标记
    int pmax[maxn<<2],padd[maxn<<2],pcov[maxn<<2];//历史标记
    
    int getint(){
    	int w=0;bool q=0;
    	char c=getchar();
    	while((c>'9'||c<'0')&&c!='-') c=getchar();
    	if(c=='-') c=getchar(),q=1;
    	while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
    	return q?-w:w;
    }
    
    void update(int u){
    	nmax[u]=max(nmax[u<<1],nmax[u<<1|1]);
    	pmax[u]=max(pmax[u<<1],pmax[u<<1|1]);
    }
    
    void pushdown(int u){
    	for(int i=0,v;i<2;i++){
    		v=u<<1|i;
    		pmax[v]=max(pmax[v],nmax[v]+padd[u]);
    		pmax[v]=max(pmax[v],pcov[u]);
    		if(ncov[v]==INF) padd[v]=max(padd[v],nadd[v]+padd[u]);
    		else pcov[v]=max(pcov[v],ncov[v]+padd[u]);
    		if(nadd[u]){
    			nmax[v]+=nadd[u];
    			if(ncov[v]==INF) nadd[v]+=nadd[u];
    			else ncov[v]+=nadd[u];
    		}
    		if(ncov[u]!=INF){
    			nmax[v]=ncov[u];
    			ncov[v]=ncov[u]; nadd[v]=0;
    			pcov[v]=max(pcov[v],pcov[u]);
    		}
    	}
    	padd[u]=nadd[u]=0,pcov[u]=ncov[u]=INF;
    }
    
    void build(int u,int l,int r){
    	pcov[u]=ncov[u]=INF;
    	int lc=u<<1,lv=u<<1|1,mid=(l+r)>>1;
    	if(l==r) nmax[u]=pmax[u]=getint();
    	else build(lc,l,mid),build(lv,mid+1,r),update(u);
    }
    
    void query(int u,int l,int r){
    	if(l!=r) pushdown(u);
    	if(l>=L && r<=R) _nm=max(_nm,nmax[u]),_pm=max(_pm,pmax[u]);
    	else{
    		int mid=(l+r)>>1;
    		if(L<=mid) query(u<<1,l,mid);
    		if(R>mid) query(u<<1|1,mid+1,r);
    	}
    }
    
    void add(int u,int l,int r){
    	if(l!=r) pushdown(u);
    	if(l>=L && r<=R)
    		if(_) padd[u]=nadd[u]=z,pmax[u]=max(pmax[u],nmax[u]+=z);
    		else pcov[u]=ncov[u]=z,pmax[u]=max(pmax[u],nmax[u]=z);
    	else{
    		int mid=(l+r)>>1;
    		if(L<=mid) add(u<<1,l,mid);
    		if(R>mid) add(u<<1|1,mid+1,r);
    		update(u);
    	}
    }
    
    int main(){
    	File("a");
    	n=getint(),build(1,1,n);
    	m=getint(); char c;
    	while(m--){
    		c=getchar();
    		while(c!='A' && c!='Q' && c!='P' && c!='C') c=getchar();
    		L=getint(); R=getint();
    		if(c=='Q' || c=='A'){
    			_nm=_pm=INF; query(1,1,n);
    			printf("%d
    ",c=='Q'?_nm:_pm);
    		}
    		else{
    			z=getint(); _=c=='P';
    			add(1,1,n);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    uva558 Wormholes SPFA 求是否存在负环
    管理经验(一)——怎样当好一个管理者
    41. 百度面试题:字符串的排列(字符串)
    24L01/SI24R1调试笔记
    中英文对照 —— 学术概念
    matlab 稀疏矩阵(sparse matrix)
    matlab 稀疏矩阵(sparse matrix)
    matlab 可变参数与默认参数设置
    matlab 可变参数与默认参数设置
    卷积、卷积矩阵(Convolution matrix)与核(Kernel)
  • 原文地址:https://www.cnblogs.com/lcf-2000/p/6575689.html
Copyright © 2011-2022 走看看