论文:
Part1:http://www.cs.ust.hk/mjg_lib/bibs/DPSu/DPSu.Files/0211028.pdf
Part2:http://www.cs.ust.hk/mjg_lib/bibs/DPSu/DPSu.Files/0213017.pdf
不得不说,确实很nb
完全想不到
代码:
#include<bits/stdc++.h>
#define jk(i,j,k) for(int i=(j);i<=(k);i++)
#define X first
#define Y second
#define pb push_back
#define ll long long
#define pi std::pair<int,int>
int rd(){int da=0;register char ch=0,w=1;while(ch!='-'&&(ch>'9'||ch<'0'))ch=getchar();(ch=='-')&&(w=-1,ch=getchar());while(ch>='0'&&ch<='9'){da=da*10+ch-'0';ch=getchar();}return da*w;}
void P(int v){if(v<0){putchar('-');v=-v;}if(v>9)P(v/10);putchar(v%10+'0');}
#define N 1551
int n;ll w[N],pr[N],R;
struct No{
int id,u,v,l;ll b,mu,x,d,k;
bool fi(No b)const{return u<=b.u&&b.v<=v;}
ll ca()const{return x/d;}
bool operator<(No b)const{return ca()<b.ca();}
}h[N];
int c,V[N],C,I[N],s[N],tp;
std::vector<int>ch[N];std::vector<No>mu[N];
std::priority_queue<No>Q[N];
void Ad(int u,int v){h[++c]=(No){c,u,v,w[u]<w[v]?u:v,pr[v]-pr[u]-w[u]*w[v],w[u]*w[v]};}
void ad(int u,No&x){Q[I[u]].push(x);mu[x.u].pb(x);mu[x.v].pb(x);}
void rm(int u){
mu[Q[I[u]].top().u].pop_back(),mu[Q[I[u]].top().v].pop_back();
Q[I[u]].pop();
}
ll cal(int u){
if(u==1)return w[1]*w[2]+w[1]*w[n];
No v=h[u];bool f=0;if(v.u^v.l)f=1,std::swap(v.u,v.v);
return mu[v.u].empty()||!v.fi(mu[v.u].back())?w[v.u]*w[v.u+(f?-1:1)]:mu[v.u].back().mu;
}
void mer(int u){
int mx=-1;
for(auto&it:ch[u])if(mx==-1||V[mx]<V[it])mx=it;
I[u]=I[mx];
auto&r=Q[I[u]=I[mx]];
for(auto&i:ch[u])
for(int v=I[i];i^mx&&!Q[v].empty();Q[v].pop())r.push(Q[v].top());
}
void dfs(int u){
No&v=h[u];V[u]=1;
if(ch[u].empty()){
I[u]=++C;v.d=v.b;
v.x=w[v.l]*(v.d+v.mu-cal(u));
ad(u,v);return;
}
v.d=v.b;
for(auto&i:ch[u]){dfs(i);V[u]+=V[i];v.d-=h[i].b;}
v.x=w[v.l]*(v.d+v.mu-cal(u));
mer(u);auto&q=Q[I[u]];
while(!q.empty()&&q.top().ca()>=w[v.l]){
v.d+=q.top().d;rm(u);v.x=w[v.l]*(v.d+v.mu-cal(u));
}
while(!q.empty()&&v.ca()<=q.top().ca()){
auto x=q.top();
v.d+=x.d;rm(u);v.x+=x.x;
}ad(u,v);
}
signed main(){
n=rd()+1;w[1]=rd();w[2]=rd();jk(i,3,n)w[i]=(rd(),rd());
std::rotate(w+1,std::min_element(w+1,w+n+1),w+n+1);
w[n+1]=w[1];jk(i,1,n+1)pr[i]=w[i]*w[i-1]+pr[i-1];
std::vector<pi>T,Z;jk(i,1,n){
while(tp>=2&&w[s[tp]]>w[i])T.pb({s[(tp--)-1],i});
s[++tp]=i;
}
for(;tp>=4;tp--)T.pb({1,s[tp-2]});
for(auto&i:T)if((i.X^1)&&(i.Y^1))Z.pb(i);
tp=0;Ad(1,n+1);
for(auto&i:Z){
Ad(i.X,i.Y);
while(tp&&h[c].fi(h[s[tp]]))ch[c].pb(s[tp--]);
s[++tp]=c;
}
while(tp)ch[1].pb(s[tp--]);
for(dfs(1);!Q[I[1]].empty();Q[I[1]].pop())R+=Q[I[1]].top().x;
printf("%lld",R);
}