ACdream 1101 瑶瑶想要玩滑梯
没想到线段树的基本使用方法这么长时间没写了还没有忘,1A的感觉还是非常爽的。
题目大意:
中文题,点此查看题目。
解题思路:
线段树的区间更新与查询。
lazy标记的使用。
当须要返回区间多个值时能够使用引用參数。
以下是代码:
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <math.h> #include <stdlib.h> using namespace std; int min(int a,int b) { if(a>b)a=b; return a; } int max(int a,int b) { if(a<b)a=b; return a; } int n,m,l,r,x; struct node1 { int num,l,r,lcnt,rcnt,mcnt; } node[100000<<2]; char s[3]; void PushUp(int l,int r,int m,int tr) { node[tr].num=-1; node[tr].l=node[tr<<1].l; node[tr].r=node[tr<<1|1].r; node[tr].lcnt=node[tr<<1].lcnt; if(node[tr<<1].lcnt==m-l+1&&node[tr<<1].r<node[tr<<1|1].l) { node[tr].lcnt+=node[tr<<1|1].lcnt; } node[tr].rcnt=node[tr<<1|1].rcnt; if(node[tr<<1|1].rcnt==r-m&&node[tr<<1].r<node[tr<<1|1].l) { node[tr].rcnt+=node[tr<<1].rcnt; } if(node[tr<<1].r<node[tr<<1|1].l) { node[tr].mcnt=node[tr<<1].rcnt+node[tr<<1|1].lcnt; } else node[tr].mcnt=0; node[tr].mcnt=max(node[tr<<1].mcnt,max(node[tr<<1|1].mcnt,max(node[tr].lcnt,max(node[tr].rcnt,node[tr].mcnt)))); } void build(int l,int r,int tr) { if(l==r) { scanf("%d",&node[tr].num); node[tr].l=node[tr].num; node[tr].r=node[tr].num; node[tr].lcnt=1; node[tr].rcnt=1; node[tr].mcnt=1; return ; } int m=(l+r)>>1; build(l,m,tr<<1); build(m+1,r,tr<<1|1); PushUp(l,r,m,tr); } void Pushdown(int l,int r,int tr) { if(node[tr].num!=-1) { node[tr<<1]=node[tr]; node[tr<<1|1]=node[tr]; node[tr].num=-1; } } void Update(int L,int R,int num,int l,int r,int tr) { if(L<=l&&r<=R) { if(node[tr].num==-1)node[tr].num=0; node[tr].num+=num; node[tr].l=num; node[tr].r=num; node[tr].lcnt=1; node[tr].rcnt=1; node[tr].mcnt=1; return ; } if(l==r)return; Pushdown(l,r,tr); int m=(l+r)>>1; if(m>=L)Update(L,R,num,l,m,tr<<1); if(m<R)Update(L,R,num,m+1,r,tr<<1|1); PushUp(l,r,m,tr); } void copy1(int a,int b,int c,int d,int e,int &a1,int &b1,int &c1,int &d1,int &e1) { a1=a; b1=b; c1=c; d1=d; e1=e; } void query(int L,int R,int l,int r,int tr,int &lcnt,int &lnum,int &rcnt,int &rnum,int &mnum) { if(L<=l&&r<=R) { mnum=node[tr].mcnt; lcnt=node[tr].lcnt; lnum=node[tr].l; rcnt=node[tr].rcnt; rnum=node[tr].r; return; } if(l==r)return; int m=(l+r)>>1,a[2]={0},b[2]={0},c[2]={0},d[2]={0},e[2]={0}; Pushdown(l,r,tr); if(m>=L) { query(L,R,l,m,tr<<1,a[0],b[0],c[0],d[0],e[0]); } if(m<R) { query(L,R,m+1,r,tr<<1|1,a[1],b[1],c[1],d[1],e[1]); } if(c[0]!=0) { if(a[1]!=0) { mnum=max(e[0],e[1]); lcnt=a[0]; lnum=b[0]; rcnt=c[1]; rnum=d[1]; if(d[0]<b[1]) { mnum=max(mnum,c[0]+a[1]); if(a[0]==e[0]&&a[0]==m-l+1) { lcnt+=a[1]; } if(c[1]==e[1]&&c[1]==r-m) { rcnt+=c[0]; } } } else { copy1(a[0],b[0],c[0],d[0],e[0],lcnt,lnum,rcnt,rnum,mnum); } } else { copy1(a[1],b[1],c[1],d[1],e[1],lcnt,lnum,rcnt,rnum,mnum); } PushUp(l,r,m,tr); return ; } int main() { scanf("%d%d",&n,&m); build(1,n,1); int temp[5]; for(int i=0; i<m; i++) { scanf("%s",s); if(s[0]=='Q') { scanf("%d%d",&l,&r); query(l,r,1,n,1,temp[0],temp[1],temp[2],temp[3],temp[4]); printf("%d\n",max(temp[0],max(temp[2],temp[4]))); } else if(s[0]=='U') { scanf("%d%d%d",&l,&r,&x); Update(l,r,x,1,n,1); } } return 0; }