• 【bzoj3064】 CPU监控


    http://www.lydsy.com/JudgeOnline/problem.php?id=3064 (题目链接)

    题意

      给出一个长度为$n$的数列$A$,同时定义一个辅助数组$B$,$B$开始与$A$完全相同。接下来进行$m$次操作, 有4种类型:

    1. 区间加法
    2. 区间覆盖
    3. 查询$A$的区间最值
    4. 查询$B$的区间最值

    Solution

      参考吉利论文。

      最恶心的就是覆盖标记和加减标记的合并=  =,一定要想清楚所有情况。

    细节

      代码略丑=  =

    代码

    // bzoj3938
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf (1ll<<30)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
    using namespace std;
    
    const int maxn=100010;
    int n,m,a[maxn];
    char ch[100];
    struct node {int l,r,nadd,padd,ncov,pcov,nmx,pmx;}tr[maxn<<2];
    
    void pushup(int k) {
    	tr[k].nmx=max(tr[k<<1].nmx,tr[k<<1|1].nmx);
    	tr[k].pmx=max(tr[k<<1].pmx,tr[k<<1|1].pmx);
    }
    void pushdown(int k) {
    	for (int x,i=0;x=k<<1|i,i<2;i++) {
    		tr[x].pmx=max(tr[x].pmx,max(tr[k].padd+tr[x].nmx,tr[k].pcov));
    		if (tr[k].ncov==-inf) {
    			tr[x].nmx+=tr[k].nadd;
    			if (tr[x].ncov==-inf) tr[x].padd=max(tr[x].padd,tr[x].nadd+tr[k].padd),tr[x].nadd+=tr[k].nadd;
    			else tr[x].pcov=max(tr[x].pcov,tr[x].ncov+tr[k].padd),tr[x].ncov=tr[x].nmx;
    		}
    		else {
    			if (tr[x].ncov==-inf) tr[x].padd=max(tr[x].padd,tr[x].nadd+tr[k].padd);
    			else tr[x].pcov=max(tr[x].pcov,tr[x].nmx+tr[k].padd);
    			tr[x].nmx=tr[x].ncov=tr[k].ncov,tr[x].pcov=max(tr[x].pcov,tr[k].pcov);
    		}
    	}
    	tr[k].ncov=tr[k].pcov=-inf;tr[k].nadd=tr[k].padd=0;
    }
    void build(int k,int s,int t) {
    	tr[k].l=s;tr[k].r=t;
    	tr[k].ncov=tr[k].pcov=-inf;
    	if (s==t) {tr[k].nmx=tr[k].pmx=a[s];return;}
    	int mid=(s+t)>>1;
    	build(k<<1,s,mid);
    	build(k<<1|1,mid+1,t);
    	pushup(k);
    }
    int query(int k,int s,int t,int op) {
    	int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
    	if (l==s && r==t) return op ? tr[k].pmx : tr[k].nmx;
    	pushdown(k);
    	if (t<=mid) return query(k<<1,s,t,op);
    	else if (s>mid) return query(k<<1|1,s,t,op);
    	else return max(query(k<<1,s,mid,op),query(k<<1|1,mid+1,t,op));
    }
    void modify(int k,int s,int t,int val,int op) {
    	int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
    	if (l==s && r==t) {
    		if (op) {
    			tr[k].pmx=max(tr[k].pmx,tr[k].nmx=val);
    			tr[k].pcov=max(tr[k].pcov,tr[k].ncov=val);
    		}
    		else {
    			tr[k].pmx=max(tr[k].pmx,tr[k].nmx+=val);
    			if (tr[k].ncov==-inf) tr[k].padd=max(tr[k].padd,tr[k].nadd+=val);
    			else tr[k].pcov=max(tr[k].pcov,tr[k].ncov=tr[k].nmx);
    		}
    		return;
    	}
    	pushdown(k);
    	if (t<=mid) modify(k<<1,s,t,val,op);
    	else if (s>mid) modify(k<<1|1,s,t,val,op);
    	else modify(k<<1,s,mid,val,op),modify(k<<1|1,mid+1,t,val,op);
    	pushup(k);
    }
    int main() {
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    	build(1,1,n);
    	scanf("%d",&m);
    	for (int x,y,z,i=1;i<=m;i++) {
    		scanf("%s%d%d",ch,&x,&y);
    		if (ch[0]=='Q') printf("%d
    ",query(1,x,y,0));
    		if (ch[0]=='A') printf("%d
    ",query(1,x,y,1));
    		if (ch[0]=='P') scanf("%d",&z),modify(1,x,y,z,0);
    		if (ch[0]=='C') scanf("%d",&z),modify(1,x,y,z,1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    第六次作业--结对编程第二次
    OneZero第四周第三次站立会议(2016.4.13)
    结对编程体会2
    OneZero第四周第二次站立会议(2016.4.12)
    关于“单元测试工具”
    OneZero第四周第一次站立会议(2016.4.11)
    OneZero第四周——预完成功能点统计
    OneZero第三周第五次站立会议(2016.4.8)
    OneZero第三周第四次站立会议(2016.4.7)
    OneZero第三周第三次站立会议(2016.4.6)
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6667157.html
Copyright © 2020-2023  润新知