题意:
给定一个长度为 N序列,编号从1 到 N。要求支持下面几种操作:
1.给一个区间[L,R] 加上一个数x
2.把一个区间[L,R] 里小于x 的数变成x
3.把一个区间[L,R] 里大于x 的数变成x
4.求区间[L,R] 的和
5.求区间[L,R] 的最大值
6.求区间[L,R] 的最小值
分析:
你听说过Segment Tree Beats么?
快去看一看吧。这题居然才只有六个操作,真的是重口难调啊。
思想还是不难的,这里就不粘课件了。
由于这题拥有着比较玄学的空间限制和比较玄学的数据范围,所以可能需要试探很多遍才能不MLE。
(如果你是指针线段树我也没啥可说的)
代码是我修改抄袭一位大神的,予以美化(好像更难读了),以便于非指针用户食用。
代码:
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N=3.7e5+5,inf=1e9; 5 struct node{ 6 int l,r,ls,rs,mnc,mxc;//标号为1代表最值 7 ll mn1,mn2,mx1,mx2;//,为2代表次值 8 ll lmn,lmx,lad,s;//c代表的是count数量,不是次 9 }t[N<<2];int cnt=0,rt,n,m,x; 10 char readchar(){ 11 static char buf[100000],*l=buf,*r=buf; 12 if(l==r) r=(l=buf)+fread(buf,1,100000,stdin); 13 if(l==r) return EOF;return *l++;} 14 int read(){ 15 int x=0,f=1;char ch=readchar(); 16 while(ch<'0'||ch>'9'){if(ch=='-') f=-f;ch=readchar();} 17 while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=readchar();}; 18 return x*f; 19 } void pushup(int cur){ 20 int ls=t[cur].ls,rs=t[cur].rs; 21 t[cur].s=t[ls].s+t[rs].s; 22 if(t[ls].mn1<t[rs].mn1) 23 t[cur].mn1=t[ls].mn1, 24 t[cur].mnc=t[ls].mnc, 25 t[cur].mn2=min(t[ls].mn2,t[rs].mn1); 26 else if(t[ls].mn1>t[rs].mn1) 27 t[cur].mn1=t[rs].mn1, 28 t[cur].mnc=t[rs].mnc, 29 t[cur].mn2=min(t[rs].mn2,t[ls].mn1); 30 else t[cur].mn1=t[ls].mn1, 31 t[cur].mnc=t[ls].mnc+t[rs].mnc, 32 t[cur].mn2=min(t[ls].mn2,t[rs].mn2); 33 if(t[ls].mx1>t[rs].mx1) 34 t[cur].mx1=t[ls].mx1, 35 t[cur].mxc=t[ls].mxc, 36 t[cur].mx2=max(t[ls].mx2,t[rs].mx1); 37 else if(t[ls].mx1<t[rs].mx1) 38 t[cur].mx1=t[rs].mx1, 39 t[cur].mxc=t[rs].mxc, 40 t[cur].mx2=max(t[rs].mx2,t[ls].mx1); 41 else t[cur].mx1=t[ls].mx1, 42 t[cur].mxc=t[ls].mxc+t[rs].mxc, 43 t[cur].mx2=max(t[ls].mx2,t[rs].mx2); 44 } void adsm(int cur,ll x){ 45 t[cur].mn1+=x;t[cur].mx1+=x; 46 if(t[cur].mn2!= inf) t[cur].mn2+=x; 47 if(t[cur].mx2!=-inf) t[cur].mx2+=x; 48 t[cur].s+=x*(t[cur].r-t[cur].l+1); 49 t[cur].lad+=x;return ; 50 } void admn(int cur,ll x){ 51 if(t[cur].mn1==t[cur].mx1) t[cur].mx1+=x; 52 if(t[cur].mn1==t[cur].mx2) t[cur].mx2+=x; 53 t[cur].lmn+=x;t[cur].mn1+=x; 54 t[cur].s+=x*t[cur].mnc;return ; 55 } void admx(int cur,ll x){ 56 if(t[cur].mn1==t[cur].mx1) t[cur].mn1+=x; 57 if(t[cur].mx1==t[cur].mn2) t[cur].mn2+=x; 58 t[cur].mx1+=x;t[cur].lmx+=x; 59 t[cur].s+=x*t[cur].mxc;return ; 60 } void pushdown(int cur){ 61 int ls=t[cur].ls,rs=t[cur].rs; 62 if(t[cur].lad) adsm(ls,t[cur].lad), 63 adsm(rs,t[cur].lad),t[cur].lad=0; 64 if(t[cur].lmn){ 65 if(t[ls].mn1<=t[rs].mn1) 66 admn(ls,t[cur].lmn); 67 if(t[ls].mn1>=t[rs].mn1) 68 admn(rs,t[cur].lmn);t[cur].lmn=0; 69 } if(t[cur].lmx){ 70 if(t[ls].mx1>=t[rs].mx1) 71 admx(ls,t[cur].lmx); 72 if(t[ls].mx1<=t[rs].mx1) 73 admx(rs,t[cur].lmx);t[cur].lmx=0; 74 } return ; 75 } void build(int l,int r,int cur){ 76 t[cur].l=l,t[cur].r=r; 77 if(l==r){ t[cur].mxc=1; 78 t[cur].ls=t[cur].rs=-1;t[cur].mnc=1; 79 t[cur].lmn=t[cur].lmx=t[cur].lad=0; 80 t[cur].s=t[cur].mx1=t[cur].mn1=read(); 81 t[cur].mn2=inf;t[cur].mx2=-inf;return ; 82 } int mid=l+r>>1; 83 t[cur].ls=cnt++;t[cur].rs=cnt++; 84 build(l,mid,t[cur].ls); 85 build(mid+1,r,t[cur].rs); 86 pushup(cur);return ; 87 } 88 #define sum(x,y) x+y; 89 #define upd(fun,lm,req,tag) 90 void fun(int l,int r,int cur){ 91 if(lm) return ; 92 if(l<=t[cur].l&&t[cur].r<=r&&req) 93 {tag;return ;} pushdown(cur); 94 int mid=t[cur].l+t[cur].r>>1; 95 if(l<=mid) fun(l,r,t[cur].ls); 96 if(mid<r) fun(l,r,t[cur].rs); 97 pushup(cur);return ; 98 } 99 #define qry(fun,typ,ret,op) 100 typ fun(int l,int r,int cur){ 101 int ls=t[cur].ls,rs=t[cur].rs; 102 if(l<=t[cur].l&&t[cur].r<=r) return ret; 103 pushdown(cur); 104 int mid=t[cur].l+t[cur].r>>1; 105 if(r<=mid) return fun(l,r,ls); 106 if(mid<l) return fun(l,r,rs); 107 return op(fun(l,r,ls),fun(l,r,rs)); 108 } 109 upd(uad,0,1,adsm(cur,x)) 110 upd(umn,t[cur].mn1>=x,t[cur].mn2>x, 111 admn(cur,x-t[cur].mn1)) 112 upd(umx,t[cur].mx1<=x,t[cur].mx2<x, 113 admx(cur,x-t[cur].mx1)) 114 qry(qsm,ll,t[cur].s,sum) 115 qry(qmx,ll,t[cur].mx1,max) 116 qry(qmn,ll,t[cur].mn1,min) 117 signed main(){ 118 rt=cnt++;n=read(); 119 build(1,n,rt);m=read(); 120 for(int l,r,op;m--;){ 121 op=read();l=read();r=read(); 122 if(op<=3) x=read(); 123 if(op==1) uad(l,r,rt); 124 if(op==2) umn(l,r,rt); 125 if(op==3) umx(l,r,rt); 126 if(op==4) printf("%lld ",qsm(l,r,rt)); 127 if(op==5) printf("%lld ",qmx(l,r,rt)); 128 if(op==6) printf("%lld ",qmn(l,r,rt)); 129 } return 0; 130 }