题解:P10540 [THUPC 2024 决赛] 古明地枣的袜子
LastKismet · · 题解
考虑换维,将操作按
每块的预处理容易扫描线做到
const int N=5e5+5,B=1e3,BC=N/B+5;
int n,m,q;
struct node{int x;ll y;int i;}ns[N];
namespace bit{
ll dat[N];
void modify(int x,ll v){for(;x<=n;x+=x&-x)dat[x]+=v;}
ll query(int x){ll v=0;for(;x;x-=x&-x)v+=dat[x];return v;}
ll query(int lq,int rq){return query(rq)-query(lq-1);}
}
int bc,lb[BC],rb[BC];
struct NODE{
vec<pii> a;
vec<vec<ll>> s,f;
void clear(){vec<pii>().swap(a),vec<vec<ll>>().swap(s),vec<vec<ll>>().swap(f);};
}dat;
vec<int> ne,la;
void build(int l,int r,NODE &dat){
if(l==r){
dat=NODE();
dat.a.pub(l,0);
dat.s.resize(1,vec<ll>(1,ns[l].y));
dat.f.resize(1,vec<ll>(1,max(ns[l].y,0ll)));
return;
}
int m=l+r>>1;NODE L,R;
build(l,m,L),build(m+1,r,R);
dat.a.resize(L.a.size()+R.a.size());
for(int it=0,lt=0,rt=0;lt<L.a.size()||rt<R.a.size();++it)
if(lt==L.a.size())dat.a[it]={R.a[rt++].fir,1};
else if(rt==R.a.size())dat.a[it]={L.a[lt++].fir,0};
else dat.a[it]=ns[L.a[lt].fir].i<ns[R.a[rt].fir].i?pii{L.a[lt++].fir,0}:pii{R.a[rt++].fir,1};
dat.f.resize(dat.a.size(),vec<ll>(dat.a.size())),dat.s.resize(dat.a.size(),vec<ll>(dat.a.size()));
int lt=-1,rt=-1;
repl(l,0,dat.a.size()){
int lr=lt,rr=rt;
repl(r,l,dat.a.size()){
++(dat.a[r].sec?rr:lr);
dat.s[l][r]=(lt<lr?L.s[lt+1][lr]:0)+(rt<rr?R.s[rt+1][rr]:0);
dat.f[l][r]=max((lt<lr?L.f[lt+1][lr]:0),(lt<lr?L.s[lt+1][lr]:0)+(rt<rr?R.f[rt+1][rr]:0));
}
++(dat.a[l].sec?rt:lt);
}
L.clear(),R.clear();
}
pii qs[N];
ll ans[N],sum[N];
void INIT(){}
void MAIN(){
read(n,q);
rep(i,1,n){int x,y;read(x,y);x<n?ns[++m]={x,y,i},void():bit::modify(i,y);}
sort(ns+1,ns+1+m,[&](node a,node b){return a.x==b.x?a.y<b.y:a.x>b.x;});
bc=(m-1)/B+1;
rep(i,1,q)read(qs[i].fir,qs[i].sec);
rep(i,1,bc){
lb[i]=(i-1)*B+1,rb[i]=min(m,i*B),build(lb[i],rb[i],dat);
ne.resize(n+2),la.resize(n+2);int it;
it=0;la[0]=-1;rep(j,1,n)la[j]=it<dat.a.size()&&ns[dat.a[it].fir].i==j?it++:la[j-1];
it=dat.a.size()-1;ne[n+1]=it+1;per(j,n,1)ne[j]=~it&&ns[dat.a[it].fir].i==j?it--:ne[j+1];
rep(j,1,q){
auto [l,r]=qs[j];
if(ne[l]<=la[r])chmax(ans[j],sum[j]+dat.f[ne[l]][la[r]]),sum[j]+=dat.s[ne[l]][la[r]];
}
}
rep(i,1,q)put(ans[i]+bit::query(qs[i].fir,qs[i].sec));
}