坑爹题面:http://uoj.ac/problem/164
正常题面:
对于一个序列支持下列5个操作:
1.区间加x
2.区间减x并与0取max
3.区间覆盖
4.单点查询
5.单点历史最大值查询
题解:
每个区间维护一个标记函数f(x)=max(x+a,b)
那么两个标记 f 和 g 的合并就是f(g(x))=max(x+max(fa+ga,-inf),max(fb+ga,gb))(假设f在前g在后)
区间加减就是打上max(x,0),区间覆盖就是打上max(-inf,x)
只要记录历史最大标记即可维护历史最大值
code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 typedef long long int64; 8 char ch; 9 bool ok; 10 void read(int &x){ 11 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==‘-‘) ok=1; 12 for (x=0;isdigit(ch);x=x*10+ch-‘0‘,ch=getchar()); 13 if (ok) x=-x; 14 } 15 const int maxn=500005; 16 const int64 inf=4557430888798830399LL; 17 int n,m,val[maxn],op,l,r,x; 18 typedef pair<int64,int64> PII; 19 #define a first 20 #define b second 21 PII operator+(const PII &x,const PII &y){return make_pair(max(x.a+y.a,-inf),max(x.b+y.a,y.b));} 22 PII max(const PII &x,const PII &y){return make_pair(max(x.a,y.a),max(x.b,y.b));} 23 struct Seg{ 24 #define ls k<<1 25 #define rs (k<<1)+1 26 PII now[maxn<<2],ever[maxn<<2]; 27 void build(int k,int l,int r){ 28 if (l==r){now[k]=ever[k]=make_pair(val[l],0);return;} 29 int m=(l+r)>>1; 30 build(ls,l,m),build(rs,m+1,r); 31 } 32 void pushdown(int k){ 33 ever[ls]=max(ever[ls],now[ls]+ever[k]); 34 ever[rs]=max(ever[rs],now[rs]+ever[k]); 35 now[ls]=now[ls]+now[k],now[rs]=now[rs]+now[k]; 36 now[k]=ever[k]=make_pair(0,0); 37 } 38 void modify(int k,int l,int r,int x,int y,PII v){ 39 if (l==x&&r==y){now[k]=now[k]+v,ever[k]=max(ever[k],now[k]);return;} 40 int m=(l+r)>>1; pushdown(k); 41 if (y<=m) modify(ls,l,m,x,y,v); 42 else if (x<=m) modify(ls,l,m,x,m,v),modify(rs,m+1,r,m+1,y,v); 43 else modify(rs,m+1,r,x,y,v); 44 } 45 void add(int x,int y,int v){modify(1,1,n,x,y,make_pair(v,0));} 46 void cov(int x,int y,int v){modify(1,1,n,x,y,make_pair(-inf,v));} 47 int64 query(int k,int l,int r,int x,int op){ 48 if (l==r){ 49 if (op) return max(ever[k].a,ever[k].b); 50 else return max(now[k].a,now[k].b); 51 } 52 int m=(l+r)>>1; pushdown(k); 53 if (x<=m) return query(ls,l,m,x,op); else return query(rs,m+1,r,x,op); 54 } 55 int64 query(int x,int op){return query(1,1,n,x,op);} 56 }T; 57 int main(){ 58 read(n),read(m); 59 for (int i=1;i<=n;i++) read(val[i]); 60 T.build(1,1,n); 61 for (int i=1;i<=m;i++){ 62 read(op); 63 if (op==1) read(l),read(r),read(x),T.add(l,r,x); 64 else if (op==2) read(l),read(r),read(x),T.add(l,r,-x); 65 else if (op==3) read(l),read(r),read(x),T.cov(l,r,x); 66 else if (op==4) read(x),printf("%lld\n",T.query(x,0)); 67 else read(x),printf("%lld\n",T.query(x,1)); 68 } 69 return 0; 70 }
原文:http://www.cnblogs.com/chenyushuo/p/5418805.html