传送门
题解:
第一个操作用李超树维护一下就行了。 时间复杂度 O ( m log 2 n ) O(m \log^2 n) O(mlog2n)。
#include
using namespace std;
typedef long long LL;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
char ch=nc(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
const LL inf=2e18;
const int N=3e5+50, L=1e9, T=60;
int n,m,rt,lc[N*T],rc[N*T],tot;
LL s1[N*T],d1[N*T]; // tag1
LL s2[N*T],d2[N*T]; // tag2
inline int newnode() {
++tot;
s1[tot]=-inf; d1[tot]=0;
return tot;
}
inline LL calc(LL s,LL d,int p) {return s+d*p;}
inline void addtag1(int &k,int l,int r,LL s,LL d) {
if(!k) {k=newnode(); s1[k]=s; d1[k]=d; return;}
if(calc(s1[k],d1[k],l)<=calc(s,d,l)) swap(s1[k],s), swap(d1[k],d);
if(l==r) return;
int mid=(l+r)>>1;
if(calc(s1[k],d1[k],mid)<=calc(s,d,mid)) {
addtag1(lc[k],l,mid,s1[k],d1[k]);
s1[k]=s; d1[k]=d;
} else addtag1(rc[k],mid+1,r,s,d);
}
inline void addtag2(int k,int l,int r,LL s,LL d) {s2[k]+=s; d2[k]+=d;}
inline void add1(int &k,int l,int r,int L,int R,LL s,LL d) {
if(!k) k=newnode();
if(L<=l && r<=R) {addtag1(k,l,r,s,d); return;}
int mid=(l+r)>>1;
if(R<=mid) add1(lc[k],l,mid,L,R,s,d);
else if(L>mid) add1(rc[k],mid+1,r,L,R,s,d);
else add1(lc[k],l,mid,L,R,s,d), add1(rc[k],mid+1,r,L,R,s,d);
}
inline void add2(int &k,int l,int r,int L,int R,LL s,LL d) {
if(!k) k=newnode();
if(L<=l && r<=R) {addtag2(k,l,r,s,d); return;}
int mid=(l+r)>>1;
if(R<=mid) add2(lc[k],l,mid,L,R,s,d);
else if(L>mid) add2(rc[k],mid+1,r,L,R,s,d);
else add2(lc[k],l,mid,L,R,s,d), add2(rc[k],mid+1,r,L,R,s,d);
}
inline LL ask1(int k,int l,int r,int p) {
if(!k) return -inf;
LL val=calc(s1[k],d1[k],p);
if(l==r) return val;
int mid=(l+r)>>1;
if(p<=mid) return max(val,ask1(lc[k],l,mid,p));
else return max(val,ask1(rc[k],mid+1,r,p));
}
inline LL ask2(int k,int l,int r,int p) {
if(!k) return 0;
LL val=s2[k]+d2[k]*p;
if(l==r) return val;
int mid=(l+r)>>1;
if(p<=mid) return val+ask2(lc[k],l,mid,p);
else return val+ask2(rc[k],mid+1,r,p);
}
int main() {
n=rd(), m=rd();
for(int i=1;i<=m;i++) {
int op=rd();
if(op==1) {
int l=rd(), r=rd(), a=rd(), b=rd();
add1(rt,1,n,l,r,b-(LL)l*a,a);
} else if(op==2) {
int l=rd(), r=rd(), a=rd(), b=rd();
add2(rt,1,n,l,r,b-(LL)l*a,a);
} else {
int pos=rd();
LL val1=ask1(rt,1,n,pos);
if(val1==-inf) {puts("NA"); continue;}
LL val2=ask2(rt,1,n,pos);
printf("%lld\n",val1+val2);
}
}
}