1.构造一个完整凸包
2.普通的构造一次凸包并求答案
2.允许动态加点的凸包求答案(cf932f)
//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") //#include <immintrin.h> //#include <emmintrin.h> #include <bits/stdc++.h> using namespace std; #define rep(i,h,t) for (int i=h;i<=t;i++) #define dep(i,t,h) for (int i=t;i>=h;i--) #define ll long long #define me(x) memset(x,0,sizeof(x)) #define IL inline #define rint register int inline ll rd(){ ll x=0;char c=getchar();bool f=0; while(!isdigit(c)){if(c=='-')f=1;c=getchar();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();} return f?-x:x; } char ss[1<<24],*A=ss,*B=ss; IL char gc() { return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; } template<class T>void maxa(T &x,T y) { if (y>x) x=y; } template<class T>void mina(T &x,T y) { if (y<x) x=y; } template<class T>void read(T &x) { int f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48); while(c=gc(),c>47&&c<58) x=x*10+(c^48); x*=f; } const int mo=1e9+7; ll fsp(int x,int y) { if (y==1) return x; ll ans=fsp(x,y/2); ans=ans*ans%mo; if (y%2==1) ans=ans*x%mo; return ans; } struct cp { ll x,y; cp operator +(cp B) { return (cp){x+B.x,y+B.y}; } cp operator -(cp B) { return (cp){x-B.x,y-B.y}; } ll operator *(cp B) { return x*B.y-y*B.x; } int half() { return y < 0 || (y == 0 && x < 0); } }; int QF; struct line{ mutable ll x,y,k; bool operator <(const line o) const{ return !QF?x<o.x:k<o.k; } }; const int N=2e5; struct linec:multiset<line>{ ll div(ll a,ll b) { return a/b-((a^b)<0&&a%b); } bool xj(auto x,auto y) { if (y==end()) { x->k=1e18; return 0;} if (x->x==y->x) {x->k=y->y>x->y?1e18:-1e18;} else x->k=div(y->y-x->y,y->x-x->x); return x->k>=y->k; } void add(ll xx,ll yy) { auto z=insert({xx,yy,0}),y=z++,x=y; while (xj(y,z)) z=erase(z); if (x!=begin()&&xj(--x,y)) xj(x,y=erase(y)); while ((y=x)!=begin()&&(--x)->k>=y->k) xj(x,erase(y)); } ll query(ll x) { QF=1; auto l=*lower_bound({0,0,x}); QF=0; return -l.x*x+l.y; } }S[N]; struct re{ int a,b,c; }; int a[N],b[N]; vector<int> ve[N]; int pos[N],size[N],cnt; ll dp[N]; void dfs(int x,int y) { size[x]=1; int ans=0; for(auto v:ve[x]) if (v!=y) { dfs(v,x); size[x]+=size[v]; if (size[v]>size[ans]) ans=v; } if (ans) { pos[x]=pos[ans]; for(auto v:ve[x]) if (v!=y&&v!=ans) { for (auto u:S[pos[v]]) S[pos[x]].add(u.x,u.y); } dp[x]=S[pos[x]].query(a[x]); } else { pos[x]=++cnt; } S[pos[x]].add(-b[x],dp[x]); } int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); int n; cin>>n; rep(i,1,n) cin>>a[i]; rep(i,1,n) cin>>b[i]; rep(i,1,n-1) { int x,y; cin>>x>>y; ve[x].push_back(y); ve[y].push_back(x); } dfs(1,0); rep(i,1,n-1) cout<<dp[i]<<" "; cout<<dp[n]<<endl; return 0; }
这个板子非常短而且挺好用的
mutable能使const也能被修改