大致题意:
给出两个序列A,B,A初始为负无穷,B初始为0,有三种操作
1、在A上区间[u,v]上加一个等差数列,取与原本A序列的最大值。
2、在B上区间[u,v]上加一个等差数列。
3、给出一个点X,询问A[X]+B[X]的值。
学习一个李超线段树就ojbk了,对于每次加入的等差数列,可以转化为y=a*i+b的一条线段,用李超线段树维护所有线段
所覆盖的区间即可。数据范围比较大,线段树可以动态开点,也可以离散化。


1 #include<cstdio>
2 #include<iostream>
3 #include<cstring>
4 #include<algorithm>
5 #include<queue>
6 #include<set>
7 #include<map>
8 #include<stack>
9 #include<time.h>
10 #include<cstdlib>
11 #include<cmath>
12 #include<list>
13 using namespace std;
14 #define MAXN 10000006
15 #define eps 1e-8
16 #define For(i,a,b) for(int i=a;i<=b;i++)
17 #define Fore(i,a,b) for(int i=a;i>=b;i--)
18 #define lson l,mid
19 #define rson mid+1,r
20 #define mkp make_pair
21 #define pb push_back
22 #define cr clear()
23 #define sz size()
24 #define met(a,b) memset(a,b,sizeof(a))
25 #define iossy ios::sync_with_stdio(false)
26 #define fr freopen
27 #define pi acos(-1.0)
28 #define Vector Point
29 #define fir first
30 #define sec second
31 const long long inf=1LL<<62;
32 const int Mod=1e9+7;
33 typedef unsigned long long ull;
34 typedef long long ll;
35 typedef pair<int,int> pii;
36 typedef pair<ll,ll> pll;
37 inline int scan(){
38 int x=0,f=1;char ch=getchar();
39 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
40 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
41 return x*f;
42 }
43 struct LcSegmentTree{
44 ll k,b,sk,sb;
45 int mk;
46 int ls,rs;
47 };
48 ll ans1,ans2;
49 LcSegmentTree t[MAXN];
50 int tot=0;
51 void seg1_change(int L,int R,ll a,ll b,int l,int r,int &rt){
52 if(!rt) {
53 rt=++tot;
54 t[rt].k=0;
55 t[rt].b=-inf;
56 }
57 //cout<<L<<" "<<R<<" "<<a<<" "<<b<<" "<<l<<" "<<r<<" "<<rt<<" "<<t[rt].mk<<" "<<t[rt].k<<" "<<t[rt].b<<endl;
58 if(L==l && R==r){
59 bool f1=(t[rt].k*l+t[rt].b>=a*l+b),f2=(t[rt].k*r+t[rt].b>=a*r+b);
60 if(f1&&f2) return ;
61 if(!f1 && !f2) {t[rt].k=a,t[rt].b=b;return ;}
62 int mid=l+r>>1;
63 bool fm=t[rt].k*mid+t[rt].b>=a*mid+b;
64 if(f1){
65 if(fm) seg1_change(mid+1,R,a,b,rson,t[rt].rs);
66 else {
67 seg1_change(L,mid,t[rt].k,t[rt].b,lson,t[rt].ls);
68 t[rt].k=a;
69 t[rt].b=b;
70 }
71 }else{
72 if(fm) seg1_change(L,mid,a,b,lson,t[rt].ls);
73 else {
74 seg1_change(mid+1,R,t[rt].k,t[rt].b,rson,t[rt].rs);
75 t[rt].k=a;t[rt].b=b;
76 }
77 }
78 return ;
79 }
80 int mid=l+r>>1;
81 if(R<=mid) seg1_change(L,R,a,b,lson,t[rt].ls);
82 else if(L>mid) seg1_change(L,R,a,b,rson,t[rt].rs);
83 else seg1_change(L,mid,a,b,lson,t[rt].ls),seg1_change(mid+1,R,a,b,rson,t[rt].rs);
84 }
85 void seg2_change(int L,int R,ll a,ll b,int l,int r,int &rt){
86 if(!rt) {
87 rt=++tot;
88 t[rt].k=0;
89 t[rt].b=-inf;
90 }
91 if(L==l && R==r) {
92 t[rt].sk+=a;
93 t[rt].sb+=b;
94 return ;
95 }
96 int mid=l+r>>1;
97 if(R<=mid) seg2_change(L,R,a,b,lson,t[rt].ls);
98 else if(L>mid) seg2_change(L,R,a,b,rson,t[rt].rs);
99 else seg2_change(L,mid,a,b,lson,t[rt].ls),seg2_change(mid+1,R,a,b,rson,t[rt].rs);
100 }
101 void query(int xx,int l,int r,int rt){
102 if(!rt) return ;
103 ans1+=t[rt].sk*xx+t[rt].sb;
104 ans2=max(ans2,t[rt].k*xx+t[rt].b);
105 if(l==r) return ;
106 int mid=l+r>>1;
107 if(xx<=mid) query(xx,lson,t[rt].ls);
108 else query(xx,rson,t[rt].rs);
109 }
110 int n,m,ty,u,v,ps,rot;
111 ll a,b;
112 void solve(){
113 met(t,0);
114 tot=0;rot=0;
115 n=scan();m=scan();
116 while(m--){
117 ty=scan();
118 if(ty==3) {
119 ps=scan();
120 ans1=0;ans2=-inf;
121 query(ps,1,n,rot);
122 if(ans2<=-inf) puts("NA");
123 else printf("%lld\n",ans1+ans2);
124 }else{
125 u=scan();v=scan();a=scan();b=scan();
126 b=b-a*u;
127 if(ty==1) seg1_change(u,v,a,b,1,n,rot);
128 else seg2_change(u,v,a,b,1,n,rot);
129 }
130 }
131 }
132 int main(){
133 int t=1;
134 while(t--) solve();
135 return 0;
136 }
来源:oschina
链接:https://my.oschina.net/u/4328499/blog/3883280