[Tyvj 1518]CPU监控
题目
Bob需要一个程序来监视CPU使用率。这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事。Bob会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩和用鼠标乱点之类的事,甚至会一脚踢掉电源……这些事有的会让做这件事的这段时间内CPU使用率增加或减少一个值;有的事还会直接让CPU使用率变为一个值。当然Bob会询问:在之前给出的事件影响下,CPU在某段时间内,使用率最高是多少。有时候Bob还会好奇地询问,在某段时间内CPU曾经的最高使用率是多少。为了使计算精确,使用率不用百分比而用一个整数表示。不保证Bob的事件列表出了莫名的问题,使得使用率为负………………INPUT
第一行一个正整数T,表示Bob需要监视CPU的总时间。然后第二行给出T个数表示在你的监视程序执行之前,Bob干的事让CPU在这段时间内每个时刻的使用率达已经达到了多少。第三行给出一个数E,表示Bob需要做的事和询问的总数。接下来E行每行表示给出一个询问或者列出一条事件:Q X Y:询问从X到Y这段时间内CPU最高使用率A X Y:询问从X到Y这段时间内之前列出的事件使CPU达到过的最高使用率P X Y Z:列出一个事件这个事件使得从X到Y这段时间内CPU使用率增加ZC X Y Z:列出一个事件这个事件使得从X到Y这段时间内CPU使用率变为Z时间的单位为秒,使用率没有单位。X和Y均为正整数(X<=Y),Z为一个整数。从X到Y这段时间包含第X秒和第Y秒。保证必要运算在有符号32位整数以内。OUTPUT
对于每个询问,输出一行一个整数回答。SAMPLE
INPUT
10-62 -83 -9 -70 79 -78 -31 40 -18 -520A 2 7A 4 4Q 4 4P 2 2 -74P 7 9 -71P 7 10 -8A 10 10A 5 9C 1 8 10Q 6 6Q 8 10A 1 7P 9 9 96A 5 5P 8 10 -53P 6 6 5A 10 10A 4 4Q 1 5P 4 9 -69OUTPUT
79-70-70-57910107979-51010
解题报告
这道极其简(e)单(xin),真的是一道裸(zhi)的(zhang)线段树。
首先,我们需要维护各种奇奇怪怪的域,当前和,当前最大值,历史和,历史最大值,而历史值又不包括当前值,这就导致了lazy操作的pushdown极其好(nan)写。
没有什么好多说的,直接看这个极其漂(chou)亮(lou)的代码= =
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 const int inf=1<<31; 6 inline int read(){ 7 int sum(0),f(1); 8 char ch(getchar()); 9 while(ch<'0'||ch>'9'){ 10 if(ch=='-') 11 f=-1; 12 ch=getchar(); 13 } 14 while(ch>='0'&&ch<='9'){ 15 sum=sum*10+ch-'0'; 16 ch=getchar(); 17 } 18 return sum*f; 19 } 20 int n,m; 21 int v[100001]; 22 int padd[400001],pset[400001],pmx[400001]; 23 int nadd[400001],nset[400001],nmx[400001]; 24 inline int my_max(int a,int b){ 25 return a>b?a:b; 26 } 27 inline void pushup(int i){ 28 int l(i<<1),r(l|1); 29 pmx[i]=my_max(pmx[l],pmx[r]); 30 nmx[i]=my_max(nmx[l],nmx[r]); 31 } 32 inline void pushdown(int rt){ 33 int ch(rt<<1); 34 for(int i=0;i<=1;i++){ 35 int nowch(ch+i); 36 pmx[nowch]=my_max(pmx[nowch],my_max(padd[rt]+nmx[nowch],pset[rt])); 37 if(nset[rt]==inf){ 38 nmx[nowch]+=nadd[rt]; 39 if(nset[nowch]==inf){ 40 padd[nowch]=my_max(padd[nowch],nadd[nowch]+padd[rt]); 41 nadd[nowch]+=nadd[rt]; 42 } 43 else{ 44 pset[nowch]=my_max(pset[nowch],nset[nowch]+padd[rt]); 45 nset[nowch]=nmx[nowch]; 46 } 47 } 48 else{ 49 if(nset[nowch]==inf){ 50 padd[nowch]=my_max(padd[nowch],nadd[nowch]+padd[rt]); 51 nadd[nowch]+=padd[rt]; 52 } 53 else 54 pset[nowch]=my_max(pset[nowch],nmx[nowch]+padd[rt]); 55 nmx[nowch]=nset[rt]; 56 nset[nowch]=nset[rt]; 57 pset[nowch]=my_max(pset[rt],pset[nowch]); 58 } 59 } 60 nadd[rt]=0; 61 padd[rt]=0; 62 nset[rt]=inf; 63 pset[rt]=inf; 64 } 65 inline void build(int l,int r,int i){ 66 padd[i]=0; 67 pset[i]=inf; 68 nadd[i]=0; 69 nset[i]=inf; 70 if(l==r){ 71 pmx[i]=v[l]; 72 nmx[i]=v[l]; 73 return; 74 } 75 int lc(i<<1),rc(lc|1),mid((l+r)>>1); 76 build(l,mid,lc); 77 build(mid+1,r,rc); 78 pushup(i); 79 } 80 inline void update_set(int ll,int rr,int c,int l,int r,int i){ 81 if(ll<=l&&r<=rr){ 82 nset[i]=c; 83 nmx[i]=c; 84 pset[i]=my_max(pset[i],nset[i]); 85 pmx[i]=my_max(pmx[i],nmx[i]); 86 return; 87 } 88 pushdown(i); 89 int lc(i<<1),rc(lc|1),mid((l+r)>>1); 90 if(ll<=mid) 91 update_set(ll,rr,c,l,mid,lc); 92 if(rr>mid) 93 update_set(ll,rr,c,mid+1,r,rc); 94 pushup(i); 95 } 96 inline void update_add(int ll,int rr,int c,int l,int r,int i){ 97 if(ll<=l&&r<=rr){ 98 nmx[i]+=c; 99 pmx[i]=my_max(pmx[i],nmx[i]); 100 if(nset[i]==inf){ 101 nadd[i]+=c; 102 padd[i]=my_max(padd[i],nadd[i]); 103 } 104 else{ 105 nset[i]=nmx[i]; 106 pset[i]=my_max(pset[i],nset[i]); 107 } 108 return; 109 } 110 pushdown(i); 111 int lc(i<<1),rc(lc|1),mid((l+r)>>1); 112 if(ll<=mid) 113 update_add(ll,rr,c,l,mid,lc); 114 if(rr>mid) 115 update_add(ll,rr,c,mid+1,r,rc); 116 pushup(i); 117 } 118 inline int query_p(int ll,int rr,int l,int r,int i){ 119 if(ll<=l&&r<=rr) 120 return pmx[i]; 121 pushdown(i); 122 int lc(i<<1),rc(lc|1),mid((l+r)>>1); 123 int ret(inf); 124 if(ll<=mid) 125 ret=my_max(ret,query_p(ll,rr,l,mid,lc)); 126 if(rr>mid) 127 ret=my_max(ret,query_p(ll,rr,mid+1,r,rc)); 128 return ret; 129 } 130 inline int query_n(int ll,int rr,int l,int r,int i){ 131 if(ll<=l&&r<=rr) 132 return nmx[i]; 133 pushdown(i); 134 int lc(i<<1),rc(lc|1),mid((l+r)>>1); 135 int ret(inf); 136 if(ll<=mid) 137 ret=my_max(ret,query_n(ll,rr,l,mid,lc)); 138 if(rr>mid) 139 ret=my_max(ret,query_n(ll,rr,mid+1,r,rc)); 140 return ret; 141 } 142 int main(){ 143 n=read(); 144 for(int i=1;i<=n;i++) 145 v[i]=read(); 146 /*for(int i=1;i<=n;i++) 147 cout<<v[i]<<' ';*/ 148 build(1,n,1); 149 m=read(); 150 char op[2]; 151 while(m--){ 152 scanf("%s",op); 153 if(op[0]=='Q'){ 154 int x(read()),y(read()); 155 printf("%d ",query_n(x,y,1,n,1)); 156 continue; 157 } 158 if(op[0]=='A'){ 159 int x(read()),y(read()); 160 printf("%d ",query_p(x,y,1,n,1)); 161 continue; 162 } 163 if(op[0]=='P'){ 164 int x(read()),y(read()),z(read()); 165 update_add(x,y,z,1,n,1); 166 continue; 167 } 168 if(op[0]=='C'){ 169 int x(read()),y(read()),z(read()); 170 update_set(x,y,z,1,n,1); 171 continue; 172 } 173 }//while(1); 174 }
ps:本以为可以写到200行,后来pushdown强行压了一半,然后各种压行,形成了如此漂(chou)亮(lou)的代码风格= =