0分,点分治+斜优DP悬关求调!
查看原帖
0分,点分治+斜优DP悬关求调!
727076
hexz01楼主2024/3/26 19:16
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+7;
ll n, all_sz, H, minsz;
ll f[N], sz[N], maxsz[N], arc[N], bfsl[N], tot_arc=0, tot_bfs=0;
ll s[N], p[N], q[N], l[N], dp[N], dis[N];
ll head[N], nxt[N], to[N], tot=0;
ll len[N];
ll que[N], totq=0;
bool vis[N];
bool cmp(int x, int y){
	return (dis[x]-l[x]>dis[y]-l[y]);
}
void add(int u, int v, ll w){
	tot++;
	nxt[tot]=head[u];
	head[u]=tot;
	to[tot]=v;
	len[tot]=w;
}
void init(int x){
	for(int i=head[x];i;i=nxt[i]){
		dis[to[i]]=dis[x]+s[to[i]];
		init(to[i]);
	}
}
void getH(int x){
	// cout<<x<<endl;
	sz[x]=1;
	maxsz[x]=0;
	for(int i=head[x];i;i=nxt[i]){
		if(!vis[to[i]]){
			getH(to[i]);
			sz[x]+=sz[to[i]];
			maxsz[x]=max(maxsz[x], sz[to[i]]);
			// cout<<"sz: "<<x<<" "<<sz[x]<<" "<<sz[to[i]]<<endl;
		}
	}
	maxsz[x]=max(maxsz[x], all_sz-maxsz[x]);
	if(maxsz[x]<minsz)
		minsz=maxsz[x], H=x;
}
void dfs(int x){
	bfsl[++tot_bfs]=x;
	for(int i=head[x];i;i=nxt[i])
		if(!vis[to[i]])
			dfs(to[i]);
}
void solve(int x){
	if(all_sz<=1)
		return;
	H=x;
	minsz=all_sz;
	getH(x);
	for(int i=head[H];i;i=nxt[i])
		vis[to[i]]=1, all_sz-=sz[to[i]];
	int tmp=H;
	int root=H;
	solve(x);
	// cout<<"h: "<<root<<endl;
	tot_arc=tot_bfs=0;
	while(tmp!=x){
		arc[++tot_arc]=tmp;
		tmp=f[tmp];
	}
	arc[++tot_arc]=tmp;
	for(int i=head[root];i;i=nxt[i])
		dfs(to[i]);
	sort(bfsl+1, bfsl+tot_bfs+1, cmp);
	totq=0;
	int forb=1;
	while(forb<=tot_bfs && dis[bfsl[forb]]-l[bfsl[forb]]>dis[root])
		forb++;
	que[0]=0;
	// cout<<tot_arc<<" "<<tot_bfs<<endl;
	for(int i=1;i<=tot_arc;i++){//(dp, dis)
		while(totq>1 && (dp[arc[i]]-dp[que[totq]])/(dis[arc[i]]-dp[que[totq]])>(dp[que[totq]]-dp[que[totq-1]])/(dis[que[totq]]-dis[que[totq-1]]))
			totq--;
		totq++;
		que[totq]=arc[i];
		// cout<<"add:"<<arc[i]<<"("<<dp[arc[i]]<<","<<dis[arc[i]]<<")"<<endl;
		while(forb<=tot_bfs && (i==tot_arc || dis[bfsl[forb]]-l[bfsl[forb]]>dis[arc[i+1]])){
			int ll=1, rr=totq, min1=rr+1;
			while(ll<=rr){
				int mid=(ll+rr)>>1;
				// cout<<ll<<"<-"<<mid<<"->"<<rr<<endl;
				cout<<que[mid]<<endl;
				if(mid!=1 && p[bfsl[forb]]<1.0*(dp[que[mid]]-dp[que[mid-1]])/(dis[que[mid]]-dis[que[mid-1]]))
					ll=mid+1;
				else{
					rr=mid-1;
					min1=min(min1, mid);
				}
			}
			// cout<<1<<" "<<totq<<" "<<bfsl[forb]<<" "<<min1<<endl;
			dp[bfsl[forb]]=min(dp[bfsl[forb]], dp[que[min1]]+p[bfsl[forb]]*(dis[bfsl[forb]]-dis[que[min1]])+q[bfsl[forb]]);
			forb++;
		}
	}
	for(int i=head[root];i;i=nxt[i]){
		all_sz=sz[to[i]];
		solve(to[i]);
	}
}
int main(){
	//freopen("travel.in", "r", stdin);
	//freopen("travel.out", "w", stdout);
	cin>>n;
	int t;
	cin>>t;
	for(int i=2;i<=n;i++){
		cin>>f[i]>>s[i]>>p[i]>>q[i]>>l[i];
		add(f[i], i, s[i]);
	}
	dis[1]=0;
	init(1);
	memset(dp, 0x3f, sizeof(dp));
	dp[1]=0;
	all_sz=n;
	solve(1);
	for(int i=2;i<=n;i++)
		cout<<dp[i]<<endl;
	return 0;
}
2024/3/26 19:16
加载中...