1. 程式人生 > >解題:洛谷4314 CPU監控

解題:洛谷4314 CPU監控

題面

線段樹·二重標記(什麼鬼

用(a,b)標記表示先執行+a操作,然後對b取max,維護歷史/當前最大值和歷史/當前標記。然後我們發現區間加$x$就是$(x,-inf)$,區間賦$x$就是$(-inf,x)$。標記有兩種更新,一種是和當前的標記合併,一種是更新歷史標記。

把一個標記tag合併進當前標記ntag,顯然新標記即

$(ntag.a+tag.a,max(ntag.b+tag.a,tag.b))$

把歷史標記htag用一個標記tag更新更簡單,其實就是對應取max

那麼就可以做了:修改標記即先把當前標記和要加的標記合併,然後更新歷史標記;修改最大值將當前最大值按標記意思改,然後歷史最大值和當前最大值取max。下放標記類似

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=100005,inf=0x3f3f3f3f;
 6 struct a
 7 {
 8     int ad,mx;
 9     void init()
10     {
11         ad=0,mx=-inf;
12     }
13 }hist[4*N],nowt[4*N];
14 a operator + (a x,a y)
15
{ 16 return (a){max(-inf,x.ad+y.ad),max(x.mx+y.ad,y.mx)}; 17 } 18 a operator ^ (a x,a y) 19 { 20 return (a){max(x.ad,y.ad),max(x.mx,y.mx)}; 21 } 22 int seq[N],hmax[4*N],nmax[4*N]; 23 int n,m,t1,t2,t3; char str[10]; 24 void Pushup(int nde) 25 { 26 int ls=2*nde,rs=2*nde+1; 27 hmax[nde]=max(hmax[ls],hmax[rs]);
28 nmax[nde]=max(nmax[ls],nmax[rs]); 29 } 30 void Apply(int nde,int tsk) 31 { 32 hist[nde]=hist[nde]^(nowt[nde]+hist[tsk]); nowt[nde]=nowt[nde]+nowt[tsk]; 33 hmax[nde]=max(hmax[nde],max(nmax[nde]+hist[tsk].ad,hist[tsk].mx)); 34 nmax[nde]=max(nmax[nde]+nowt[tsk].ad,nowt[tsk].mx); 35 } 36 void Release(int nde) 37 { 38 int ls=2*nde,rs=2*nde+1; 39 Apply(ls,nde),Apply(rs,nde); 40 hist[nde].init(),nowt[nde].init(); 41 } 42 void Create(int nde,int l,int r) 43 { 44 hist[nde].init(),nowt[nde].init(); 45 if(l==r) 46 hmax[nde]=nmax[nde]=seq[l]; 47 else 48 { 49 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; 50 Create(ls,l,mid),Create(rs,mid+1,r); 51 Pushup(nde); 52 } 53 } 54 void Change(int nde,int l,int r,int nl,int nr,a tsk) 55 { 56 if(l>nr||r<nl) 57 return ; 58 else if(l>=nl&&r<=nr) 59 { 60 hist[nde]=hist[nde]^(nowt[nde]+tsk); nowt[nde]=nowt[nde]+tsk; 61 hmax[nde]=max(hmax[nde],max(nmax[nde]+tsk.ad,tsk.mx)); 62 nmax[nde]=max(nmax[nde]+tsk.ad,tsk.mx); 63 } 64 else 65 { 66 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde); 67 Change(ls,l,mid,nl,nr,tsk),Change(rs,mid+1,r,nl,nr,tsk); 68 Pushup(nde); 69 } 70 } 71 int Query(int nde,int l,int r,int nl,int nr,int typ) 72 { 73 if(l>nr||r<nl) 74 return -inf; 75 else if(l>=nl&&r<=nr) 76 return typ?nmax[nde]:hmax[nde]; 77 else 78 { 79 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde); 80 return max(Query(ls,l,mid,nl,nr,typ),Query(rs,mid+1,r,nl,nr,typ)); 81 } 82 } 83 int main() 84 { 85 scanf("%d",&n); 86 for(int i=1;i<=n;i++) 87 scanf("%d",&seq[i]); 88 Create(1,1,n),scanf("%d",&m); 89 for(int i=1;i<=m;i++) 90 { 91 scanf("%s%d%d",str,&t1,&t2); 92 if(str[0]=='Q') printf("%d\n",Query(1,1,n,t1,t2,1)); 93 else if(str[0]=='A') printf("%d\n",Query(1,1,n,t1,t2,0)); 94 else if(str[0]=='P') scanf("%d",&t3),Change(1,1,n,t1,t2,(a){t3,-inf}); 95 else if(str[0]=='C') scanf("%d",&t3),Change(1,1,n,t1,t2,(a){-inf,t3}); 96 } 97 return 0; 98 }
View Code