题解:P15884 [ICPC 2026 NAC] Jelly Fusion
考虑枚举起点,设
这样是
进一步的,我们不用枚举起点,
注意现在的转移:
:::success[code]
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+7;
const int MAXN=1e12+7;
struct LINE
{
int k,b;
LINE(){}
LINE(int kk,int bb):k(kk),b(bb){}
}line[N];
struct Li_Seg_Tree
{
int tr[N],ls[N],rs[N],cnt,root;
inline void clear()
{
for(int i=1;i<=cnt;i++)tr[i]=ls[i]=rs[i]=0;
root=cnt=0;
}
inline int calc(int id,int x){return x*line[id].k+line[id].b;}
inline bool cmp(int A,int B,int x){return calc(A,x)>calc(B,x);}
inline void insert(int &p,int l,int r,int id)
{
if(!p) p=++cnt;
if(l==r)
{
tr[p]=id;
return;
}
if(!tr[p])
{
tr[p]=id;
return;
}
if(cmp(id,tr[p],l)&&cmp(id,tr[p],r))
{
tr[p]=id;
return;
}
int mid=(l+r)>>1;
if(cmp(id,tr[p],mid)) swap(id,tr[p]);
if(cmp(id,tr[p],l)) insert(ls[p],l,mid,id);
if(cmp(id,tr[p],r)) insert(rs[p],mid+1,r,id);
}
inline int query(int p,int l,int r,int x)
{
int ans=calc(tr[p],x);
if(!p||l==r) return ans;
int mid=(l+r)>>1;
if(mid>=x) ans=max(ans,query(ls[p],l,mid,x));
else ans=max(ans,query(rs[p],mid+1,r,x));
return ans;
}
inline void insert(int id)
{
insert(root,1,N,id);
}
inline int query(int x)
{
return query(root,1,N,x);
}
}T1,T2;
int n;
int f[N];
int h[N],w[N];
inline int solve()
{
T1.clear(),T2.clear();
for(int i=0;i<=n*2+2;i++)line[i]={0,0};
for(int i=0;i<=n;i++)f[i]=0;
int pre1=0,pre2=0;
line[n*2+1]={h[1],0};
line[n*2+2]={w[1],0};
T1.insert(n*2+1);
T2.insert(n*2+2);
for(int i=1;i<=n;i++)
{
f[i]=max({pre1+h[i]*w[i],pre2,T1.query(w[i]),T2.query(h[i])});
pre1=max(pre1,f[i]);
pre2=max(pre2,f[i]+h[i+1]*w[i+1]);
line[i]={h[i+1],f[i]};
line[i+n]={w[i+1],f[i]};
T1.insert(i);
T2.insert(i+n);
// for(int j=0;j<i;j++)
// {
// f[i]=max(f[i],f[j]+max({h[i]*w[i],h[j+1]*w[j+1],h[j+1]*w[i],h[i]*w[j+1]}));
// }
}
return f[n];
}
int H[N],W[N];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
cin>>H[i]>>W[i];
int Max=0,pos=0;
for(int i=1;i<=n;i++)
{
if(H[i]>Max)
{
Max=H[i];
pos=i;
}
}
for(int i=pos,j=1;j<=n;j++,i=i%n+1)
{
h[j]=H[i];
w[j]=W[i];
}
int ans=solve();
for(int i=pos%n+1,j=1;j<=n;j++,i=i%n+1)
{
h[j]=H[i];
w[j]=W[i];
}
cout<<max(ans,solve());
}
:::