BZOJ3064: Tyvj 1518 CPU监控

n<=100000的数列支持以下操作:一、区间加;二、区间赋值;三、查区间最大;四、查区间历史版本最大。

恶心死我了。。可能很水,但我调了半天。

错误!调了两天。

这里有一个棘手问题:历史版本。

首先不看赋值操作。记俩标记——区间加add和区间历史加标记pre。其中后者的含义是“从上一次这个区间标记下传到现在,区间加(前者)标记的最大值”。这样,比如某点i的标记下传给儿子x,标记如此叠加:$pre_x>?=pre_i+add_x$,$add_x+=add_i$,同时更新区间历史版本最大值:$his_x>?=Max_x+pre_x-add_x$。

然后加入赋值操作。可以发现一个区间在标记下传前只有两个阶段:一开始只有加标记,后来只有赋值标记:打上赋值标记后,如果该区间还要加,相当于更新赋值标记。因此,分两种历史标记来搞,一个记第一阶段的$add$的最大值,一个记第二阶段$be$的最大值。下传时注意顺序。

关键点截图留念:

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<cstdio>
  5 #include<math.h>
  6 //#include<complex>
  7 //#include<ctime>
  8 #include<algorithm>
  9 using namespace std;
 10
 11 int n,m;
 12 #define maxn 100011
 13 const int inf=0x3f3f3f3f;
 14 int num[maxn];
 15 struct SMT
 16 {
 17     struct Node
 18     {
 19         int ls,rs;
 20         int add,pa,be,pb;
 21         int Max,pmax;
 22     }a[maxn<<1];
 23     int size,root;
 24     SMT() {size=root=0; a[0].Max=a[0].pmax=-inf;}
 25     void up(int x,int L,int R)
 26     {
 27         int &p=a[x].ls,&q=a[x].rs;
 28         a[x].Max=max(a[p].Max,a[q].Max);
 29         a[x].pmax=max(a[p].pmax,a[q].pmax);
 30     }
 31     void addsingle(int x,int L,int R,int v,int pv)
 32     {
 33         if (a[x].be!=-inf)
 34         {besingle(x,L,R,a[x].be+v,a[x].be+pv); return;}
 35         a[x].pa=max(a[x].pa,a[x].add+pv),a[x].add+=v;
 36         a[x].Max+=v; a[x].pmax=max(a[x].pmax,a[x].pa+a[x].Max-a[x].add);
 37     }
 38     void besingle(int x,int L,int R,int v,int pv)
 39     {
 40         a[x].pb=max(a[x].pb,pv); a[x].add=0; a[x].be=v;
 41         a[x].Max=v; a[x].pmax=max(a[x].pmax,a[x].pb);
 42     }
 43     void down(int x,int L,int R)
 44     {
 45         int &p=a[x].ls,&q=a[x].rs,mid=(L+R)>>1;
 46         if (a[x].add || a[x].pa)
 47         addsingle(p,L,mid,a[x].add,a[x].pa),addsingle(q,mid+1,R,a[x].add,a[x].pa),a[x].add=a[x].pa=0;
 48         if (a[x].be!=-inf || a[x].pb!=-inf)
 49         besingle(p,L,mid,a[x].be,a[x].pb),besingle(q,mid+1,R,a[x].be,a[x].pb),a[x].be=a[x].pb=-inf;
 50     }
 51     void build(int &x,int L,int R)
 52     {
 53         x=++size;
 54         a[x].add=a[x].pa=0; a[x].be=a[x].pb=-inf;
 55         if (L==R) {a[x].ls=a[x].rs=0; a[x].Max=a[x].pmax=num[L];return;}
 56         int mid=(L+R)>>1;
 57         build(a[x].ls,L,mid); build(a[x].rs,mid+1,R); up(x,L,R);
 58     }
 59     void build() {build(root,1,n);}
 60     int ql,qr,v;
 61     void Add(int &x,int L,int R)
 62     {
 63         if (ql<=L && R<=qr) {addsingle(x,L,R,v,v); return;}
 64         down(x,L,R);
 65         int mid=(L+R)>>1;
 66         if (ql<=mid) Add(a[x].ls,L,mid);
 67         if (qr> mid) Add(a[x].rs,mid+1,R);
 68         up(x,L,R);
 69     }
 70     void add(int L,int R,int v)
 71     {
 72         ql=L; qr=R; this->v=v;
 73         Add(root,1,n);
 74     }
 75     void Be(int &x,int L,int R)
 76     {
 77         if (ql<=L && R<=qr) {besingle(x,L,R,v,v); return;}
 78         down(x,L,R);
 79         int mid=(L+R)>>1;
 80         if (ql<=mid) Be(a[x].ls,L,mid);
 81         if (qr> mid) Be(a[x].rs,mid+1,R);
 82         up(x,L,R);
 83     }
 84     void be(int L,int R,int v)
 85     {
 86         ql=L; qr=R; this->v=v;
 87         Be(root,1,n);
 88     }
 89     int Qmax(int &x,int L,int R)
 90     {
 91         if (ql<=L && R<=qr) return a[x].Max;
 92         down(x,L,R);
 93         int mid=(L+R)>>1,ans=-inf;
 94         if (ql<=mid) ans=Qmax(a[x].ls,L,mid);
 95         if (qr> mid) ans=max(ans,Qmax(a[x].rs,mid+1,R));
 96         return ans;
 97     }
 98     int qmax(int L,int R)
 99     {
100         ql=L; qr=R;
101         return Qmax(root,1,n);
102     }
103     int Qpmax(int &x,int L,int R)
104     {
105         if (ql<=L && R<=qr) return a[x].pmax;
106         down(x,L,R);
107         int mid=(L+R)>>1,ans=-inf;
108         if (ql<=mid) ans=Qpmax(a[x].ls,L,mid);
109         if (qr> mid) ans=max(ans,Qpmax(a[x].rs,mid+1,R));
110         return ans;
111     }
112     int qpmax(int L,int R)
113     {
114         ql=L; qr=R;
115         return Qpmax(root,1,n);
116     }
117 }t;
118
119 int main()
120 {
121     scanf("%d",&n);
122     for (int i=1;i<=n;i++) scanf("%d",&num[i]);
123     t.build();
124
125     scanf("%d",&m);
126     int x,y,z; char id;
127     while (m--)
128     {
129         while ((id=getchar())<‘A‘ || id>‘Z‘);
130         if (id==‘A‘) scanf("%d%d",&x,&y),printf("%d\n",t.qpmax(x,y));
131         else if (id==‘Q‘) scanf("%d%d",&x,&y),printf("%d\n",t.qmax(x,y));
132         else if (id==‘P‘) scanf("%d%d%d",&x,&y,&z),t.add(x,y,z);
133         else scanf("%d%d%d",&x,&y,&z),t.be(x,y,z);
134     }
135     return 0;
136 }

原文地址:https://www.cnblogs.com/Blue233333/p/8448451.html

时间: 2024-10-07 08:08:56

BZOJ3064: Tyvj 1518 CPU监控的相关文章

bzoj3064: Tyvj 1518 CPU监控 线段树

线段树维护两个值四个标记,注意打标记的顺序. #include<bits/stdc++.h> #define N (1<<18) #define M (l+r>>1) #define P (k<<1) #define S (k<<1|1) #define L l,M,P #define R M+1,r,S #define Z int l=1,int r=n,int k=1 using namespace std; int n; typedef i

[补档][Tyvj 1518]CPU监控

题目 Bob需要一个程序来监视CPU使用率.这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事. Bob会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩和用鼠标乱点之类的事,甚至会一脚踢掉电源--这些事有的会让做这件事的这段时间内CPU使用率增加或减少一个值:有的事还会直接让CPU使用率变为一个值. 当然Bob会询问:在之前给出的事件影响下,CPU在某段时间内,使用率最高是多少.有时候Bob还会好奇地询问,在某段时间内CPU曾经的最高使用率是多少. 为了使计

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 i

C#实现对远程服务器的内存和CPU监控

C#实现对远程服务器的内存和CPU监控小记 1.  主要使用到的组件有System.Management.dll 2.  主要类为 :ManagementScope 连接远程服务器示例代码: 1 private const string PROPERTY_CAPACITY = "Capacity"; 2 private const string PROPERTY_AVAILABLE_BYTES = "AvailableBytes"; 3 private const

CPU监控 解题报告

CPU监控 这种题就需要小黄鸭调试法,不行就重构,动态gdb可能会死人,一堆tag的... 维护历史最值的一个核心是历史最值tag,它的意义是从上一次这个点下放tag之后到当前时刻的这个点的tag达到过的最大值. 我们注意到tag的作用是按找时间限制的,所以我们可以认为历史最大tag是一个前缀最大值. 有了历史最值tag,我们就可以完成pushdown的工作辣 就把历史tag放给儿子的历史tag和历史最值,这时候更新需要用儿子的当前值结合自己的历史最大进行更新. 对这个题维护一个二元组\(tag

安卓app测试之cpu监控

安卓app测试之cpu监控,如何获取监控的cpu数据呢? 一.通过Dumpsys 来取值 1.adb shell dumpsys cpuinfo 二.top 1.top -d 1|grep packageName adb shell "top -d 1|grep tv.danmaku.bili" 原文地址:https://www.cnblogs.com/wuzm/p/10969003.html

P4314 CPU监控

P4314 CPU监控 好一道神仙题 思路来源于yyb神仙 题目要求我们支持4个操作: 区间赋值 区间加 区间最大值 区间历史最大值 这第四个操作简直是BUG一样的存在 思考一下,发现难点在于维护区间历史最大值 先打完这些: #include<bits/stdc++.h> using namespace std; const int N=100005; #define INF 1050000000 struct TAG{ #define il inline int a,b; il void c

【bzoj3064】 CPU监控

http://www.lydsy.com/JudgeOnline/problem.php?id=3064 (题目链接) 题意 给出一个长度为$n$的数列$A$,同时定义一个辅助数组$B$,$B$开始与$A$完全相同.接下来进行$m$次操作, 有4种类型: 区间加法 区间覆盖 查询$A$的区间最值 查询$B$的区间最值 Solution 参考吉利论文. 最恶心的就是覆盖标记和加减标记的合并=  =,一定要想清楚所有情况. 细节 代码略丑=  = 代码 // bzoj3938 #include<al

【BZOJ3064】【Tyvj1518】CPU监控 裸线段树

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43271091"); } 题解:显然是裸的线段树,连区间合并都没有,更别提可持久化了... 水得一比,但是也相当恶心.. 维护一下: 目前线段 最大值.覆盖值.增加值. 历史线段 最大值.覆盖值.增加值. 然后覆盖值是赋-inf还是再加个flag记录有