社区讨论
洛谷是 0!求卡常
P5611[Ynoi2013] D2T2参与者 5已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @mj9zxq2s
- 此快照首次捕获于
- 2025/12/17 20:37 2 个月前
- 此快照最后确认于
- 2025/12/17 21:16 2 个月前
如题,qoj 上过了(虽然好像是最慢解),洛谷上全 T 了。
我甚至写的时候就把分治转成迭代了,讲道理常数不应该大啊???
CPP#include<bits/stdc++.h>
using namespace std;
namespace Mortis{
constexpr int Bl=256,Bt=391,N=Bl*Bt,M=100000;
using ll=long long;
struct rain{
ll mxs,ls,rs,s;
rain():mxs(0),ls(0),rs(0),s(0){}
rain(ll x){mxs=ls=rs=max(x,0ll),s=x;}
void operator+=(const rain&o){
mxs=max({mxs,o.mxs,rs+o.ls}),ls=max(ls,s+o.ls),rs=max(o.rs,o.s+rs),s+=o.s;
}
rain operator+(const rain&o)const{
rain tmp=*this;tmp+=o;
return tmp;
}
};
int A[N],B[N];
struct{
int l,r,L,R,LL,RR;
rain res;
}qr[M];int m;
void build(int bid){
auto a=A+bid*Bl;
static int b[Bl],c[Bl],d[Bl];
static rain f[Bl][Bl],g1[Bl][Bl],g2[Bl][Bl];
static int Ml[N],Mr[N];
for(int i=0;i<Bl;++i)b[i]=i,f[i][0]=a[i];
for(int l=0;(1<<l)<Bl;++l)
for(int i=0;i<Bl;i+=(1<<(l+1))){
for(int j=0,p=0,q=(1<<l);j<(1<<(l+1));++j)
if(p<(1<<l)&&(q==(1<<(l+1))||a[b[p+i]]<a[b[q+i]]))c[p++]=j;
else c[q++]=j;
for(int j=0;j<(1<<l);++j){
for(int k=0;k<=j;++k){
g1[j][k]=f[i+j][k],f[i+j][k]={};
g2[j][k]=f[i+j+(1<<l)][k],f[i+j+(1<<l)][k]={};
}
for(int k=j+1;k<=(j+(1<<l));++k)f[i+j+(1<<l)][k]={};
}
for(int j=0;j<(1<<l);++j){
int jl=c[j],jr=(j+1<(1<<l)?c[j+1]:(1<<(l+1)))-1;
for(int k=0;k<=j;++k){
int kl=k?c[k-1]+1:0,kr=c[k];
for(int jj=jl;jj<=jr;++jj)
for(int kk=kl;kk<=kr;++kk)
f[i+jj][kk]+=g1[j][k];
}
}
for(int j=0;j<(1<<l);++j){
int jl=c[j+(1<<l)],jr=(j+1<(1<<l)?c[j+(1<<l)+1]:(1<<(l+1)))-1;
for(int k=0;k<=j;++k){
int kl=k?c[k+(1<<l)-1]+1:0,kr=c[k+(1<<l)];
for(int jj=jl;jj<=jr;++jj)
for(int kk=kl;kk<=kr;++kk)
f[i+jj][kk]+=g2[j][k];
}
}
for(int j=0;j<(1<<(l+1));++j)d[c[j]]=b[i+j];
for(int j=0;j<(1<<(l+1));++j)b[i+j]=d[j];
}
for(int i=0,j=0;i<N;++i){
for(;j<Bl&&a[b[j]]<B[i];++j);
Ml[i]=j;
}
for(int i=N-1,j=Bl-1;i>=0;--i){
for(;j>=0&&a[b[j]]>B[i];--j);
Mr[i]=j;
}
int l=bid*Bl,r=(bid+1)*Bl-1;
for(int i=0;i<m;++i){
if(qr[i].r<l)continue;
if(qr[i].l>r)continue;
if(qr[i].LL>qr[i].RR)continue;
if(l<qr[i].l||qr[i].r<r){
int ll=max(qr[i].l,l),rr=min(qr[i].r,r);
for(int j=ll;j<=rr;++j)
if(qr[i].L<=A[j]&&A[j]<=qr[i].R)
qr[i].res+=A[j];
}else if(Ml[qr[i].LL]<=Mr[qr[i].RR])qr[i].res+=f[Mr[qr[i].RR]][Ml[qr[i].LL]];
}
}
void main(){
int n;
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i)scanf("%d",A+i),B[i]=A[i];
sort(B,B+N);
for(int i=0,l,r,L,R;i<m;++i){
scanf("%d%d%d%d",&l,&r,&L,&R),--l,--r;
int LL=lower_bound(B,B+N,L)-B,RR=upper_bound(B,B+N,R)-B-1;
qr[i]={l,r,L,R,LL,RR,(rain){}};
}
for(int i=0;i<Bt;++i)build(i);
for(int i=0;i<m;++i)printf("%lld\n",qr[i].res.mxs);
}
}
int main(){
Mortis::main();
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...