题解 法阵
发现一个区间内前 \(\log\) 大的数不可能对答案没贡献
于是一个乱搞是线段树取出前 \(\log\) 大的数,单调栈 \(O(n^2)\) 在这 \(\log\) 个中求答案
复杂度 \(O(n\log^2 n)\),可以过 zhengrui 的 200 组数据
但是很好卡,考虑最大的数特别大但是能跟它配对的数很小以至于都不在前 \(\log\) 大里
题目来源:「JOI Open 2019」三级跳
正解先咕着
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 500010
#define fir first
#define sec second
#define pb push_back
#define ll long long
// #define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n, m;
ll a[N];
namespace force{
ll query(int l, int r) {
ll ans=0;
for (int y=l+1; y<r; ++y)
for (int x=l; x<y; ++x)
for (int z=y+(y-x); z<=r; ++z)
ans=max(ans, a[x]+a[y]+a[z]);
return ans;
}
void solve() {
for (int i=1,l,r; i<=m; ++i) {
l=read(); r=read();
printf("%lld\n", query(l, r));
}
}
}
namespace task1{
ll ans[N], bit[5010];
int mx[5010][5010];
vector<pair<int, int>> que[5010];
inline void upd(int i, ll dat) {for (; i; i-=i&-i) bit[i]=max(bit[i], dat);}
inline ll query(int i) {ll ans=0; for (; i<=n; i+=i&-i) ans=max(ans, bit[i]); return ans;}
void solve() {
for (int i=1,l,r; i<=m; ++i) {
l=read(); r=read();
que[r].pb({l, i});
}
for (int i=1; i<=n; ++i)
for (int j=i; j<=n; ++j)
mx[i][j]=max(mx[i][j-1], (int)a[j]);
for (int r=3; r<=n; ++r) {
for (int l=r-2; l; --l)
upd(l, a[l]+a[r]+mx[l+1][(l+r)/2]);
for (auto it:que[r]) ans[it.sec]=query(it.fir);
}
for (int i=1; i<=m; ++i) printf("%lld\n", ans[i]);
}
}
namespace task2{
ll ans;
int pos[N], sta[N], top;
void solve() {
for (int i=1; i<=n; ++i) pos[i]=i;
sort(pos+1, pos+n+1, [](int i, int j){return a[i]>a[j];});
for (int i=1; i<=200; ++i) sta[++top]=pos[i];
for (int i=1; i<=n; ++i) cout<<a[pos[i]]<<' '; cout<<endl;
sort(sta+1, sta+top+1);
for (int x=1; x<=top; ++x)
for (int y=x+1; y<=top; ++y)
for (int z=y+1; z<=top; ++z)
if (sta[y]-sta[x]<=sta[z]-sta[y])
ans=max(ans, a[sta[x]]+a[sta[y]]+a[sta[z]]);
cout<<ans<<endl;
}
}
namespace task3{
int sta[50], q[50], top, ql, qr;
int tl[N<<2], tr[N<<2];
struct buc{
int dat[18], siz;
buc():siz(0) {}
inline int& operator [] (int t) {return dat[t];}
// inline ll qmax() {
// ll ans=0;
// sort(dat+1, dat+siz+1);
// cout<<"dat: "; for (int i=1; i<=siz; ++i) cout<<dat[i]<<' '; cout<<endl;
// for (int x=1; x<=siz; ++x)
// for (int y=x+1; y<=siz; ++y)
// for (int z=y+1; z<=siz; ++z)
// if (dat[y]-dat[x]<=dat[z]-dat[y])
// ans=max(ans, a[dat[x]]+a[dat[y]]+a[dat[z]]), cout<<dat[x]<<' '<<dat[y]<<' '<<dat[z]<<endl;
// return ans;
// }
inline ll qmax() {
ll ans=0; top=0; ql=1; qr=0;
sort(dat+1, dat+siz+1);
for (int i=1; i<=siz; ++i) {
while (ql<=qr && a[q[qr]]<=a[dat[i]]) --qr;
q[++qr]=dat[i];
}
// for (int i=ql; i<=qr; ++i) cout<<q[i]<<' '; cout<<endl;
for (int y=1; y<=siz; ++y) {
// cout<<"y: "<<dat[y]<<endl;
if (q[ql]==dat[y]) ++ql;
for (int x=top,z=ql; x; --x) {
while (z<=qr && dat[y]-sta[x]>q[z]-dat[y]) ++z;
// if (z<=qr) cout<<"xz: "<<sta[x]<<' '<<q[z]<<endl;
if (z<=qr) ans=max(ans, a[sta[x]]+a[dat[y]]+a[q[z]]);
}
while (top && a[sta[top]]<=a[dat[y]]) --top;
sta[++top]=dat[y];
}
return ans;
}
}dat[N<<2];
inline buc operator + (buc x, buc y) {
buc ans;
int p1=1, p2=1, tot=min(x.siz+y.siz, 17);
for (int i=1; i<=tot; ++i) {
if (p1>x.siz) ans[i]=y[p2++];
else if (p2>y.siz) ans[i]=x[p1++];
else {
if (a[x[p1]]>=a[y[p2]]) ans[i]=x[p1++];
else ans[i]=y[p2++];
}
}
ans.siz=tot;
return ans;
}
#define tl(p) tl[p]
#define tr(p) tr[p]
#define siz(p) siz[p]
#define dat(p) dat[p]
// inline void pushup(int p) {dat(p)=dat(p<<1)+dat(p<<1|1);}
void build(int p, int l, int r) {
tl(p)=l; tr(p)=r;
if (l==r) {dat(p)[1]=l; dat(p).siz=1; return ;}
int mid=(l+r)>>1;
build(p<<1, l, mid);
build(p<<1|1, mid+1, r);
dat(p)=dat(p<<1)+dat(p<<1|1);
}
buc query(int p, int l, int r) {
if (l<=tl(p)&&r>=tr(p)) return dat(p);
int mid=(tl(p)+tr(p))>>1;
if (l<=mid&&r>mid) return query(p<<1, l, r)+query(p<<1|1, l, r);
else if (l<=mid) return query(p<<1, l, r);
else return query(p<<1|1, l, r);
}
void solve() {
build(1, 1, n);
for (int i=1,l,r; i<=m; ++i) {
l=read(); r=read();
buc t=query(1, l, r);
for (int i=1; i<=t.siz; ++i) cout<<t[i]<<' '; cout<<endl;
printf("%lld\n", query(1, l, r).qmax());
}
}
}
signed main()
{
freopen("fz.in", "r", stdin);
freopen("fz.out", "w", stdout);
n=read();
for (int i=1; i<=n; ++i) a[i]=read();
m=read();
// force::solve();
// task2::solve();
// task3::solve();
task::solve();
return 0;
}