QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#54890#3047. Wind of ChangeXiejiadongRE 0ms0kbC++4.3kb2022-10-11 11:05:232022-10-11 11:05:26

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-10-11 11:05:26]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2022-10-11 11:05:23]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+7;
typedef long  long LL;
int n;	
template<typename _T>inline void read(_T &x)
{
	x=0;static char c;c=getchar(); bool f=0; 
	for(;c<'0'||c>'9';c=getchar()) f|=(c=='-');
	for(;c>='0'&&c<='9';c=getchar())
	x=x*10+(c^48);
	x=(f)?(-x):x;
}
int h[N],K=0;
LL E[N],ans[N];
bool key[N];
namespace Tree1
{
	struct edge
	{
		int y,next;
		LL v;
	}e[2*N];
	int link[N],t=0;
	inline void add(int x,int y,LL v)
	{
		e[++t].y=y;
		e[t].v=v;
		e[t].next=link[x];
		link[x]=t;
	}
	int dep[N],seq[2*N],len=0,st[2*N][18],tot=0,lg[2*N];
	int dfn[N];
	LL dis[N];
	void dfs(int x,int pre)
	{
		dep[x]=dep[pre]+1;
		seq[++len]=x;
		dfn[x]=len;
		for(int i=link[x];i;i=e[i].next)
		{
			int y=e[i].y;
			if(y==pre) continue;
			dis[y]=dis[x]+e[i].v;
			dfs(y,x);
			seq[++len]=x;
		}
	}
	inline int Min(int x,int y){return dep[x]<dep[y]?x:y;}
	inline int LCA(int x,int y)
	{
		int l=dfn[x],r=dfn[y];
		if(l>r) swap(l,r);
		int k=lg[r-l+1];
		return Min(st[l][k],st[r-(1<<k)+1][k]);
	}
	LL dist(int x,int y)
	{
		return dis[x]+dis[y]-2ll*dis[LCA(x,y)];
	}
	void init()
	{
		for(int i=1;i<n;i++)
		{
			int x,y,v;
			read(x);read(y);read(v);
			add(x,y,v);
			add(y,x,v);
		}
		dfs(1,0);
		for(int i=2;i<=len;i++)
		lg[i]=lg[i>>1]+1;
		for(int i=1;i<=len;i++)
		st[i][0]=seq[i];
		for(int k=1;k<=lg[len];k++)
		for(int i=1;i<=len&&i+(1<<k)-1<=len;i++)
		st[i][k]=Min(st[i][k-1],st[i+(1<<(k-1))][k-1]);
	}
	inline void storage(int x,int y)
	{
		add(x,y,dist(x,y));
	}
	inline bool cmp(int x,int y)
	{
		return dfn[x]<dfn[y];
	}
	int sta[N],top=0;
	LL mx[N],smx[N],dp[N];
	void tree_dp(int x)
	{
		mx[x]=smx[x]=1e18;
		dp[x]=1e18;
		for(int i=link[x];i;i=e[i].next)
		{
			int y=e[i].y;
			tree_dp(y);
			if(mx[y]+e[i].v<=mx[x]) smx[x]=mx[x],mx[x]=mx[y]+e[i].v;
			else if(mx[y]+e[i].v<=smx[x]) smx[x]=mx[y]+e[i].v;
		}
		if(key[x])
		{
			ans[x]=min(ans[x],mx[x]+E[x]);		
			if(mx[x]>=E[x]) smx[x]=mx[x],mx[x]=E[x];
			else if(smx[x]>=E[x]) smx[x]=E[x];
		}
	}
	void Rotate(int x)
	{
		if(key[x])ans[x]=min(ans[x],dp[x]+E[x]);
		for(int i=link[x];i;i=e[i].next)
		{
			int y=e[i].y;
			if(mx[x]==mx[y]+e[i].v) dp[y]=smx[x]+e[i].v;
			else dp[y]=mx[x]+e[i].v;
			dp[y]=min(dp[y],dp[x]+e[i].v);
			Rotate(y);
		}
	}
	void Build()
	{
		sort(h+1,h+K+1,cmp);
		t=0;
		top=0;
		sta[++top]=1;
		link[1]=0;
		for(int i=1;i<=K;i++)
		{
			if(h[i]==1) continue;
			int lca=LCA(h[i],sta[top]);
			if(lca!=sta[top])
			{
				while(dfn[sta[top-1]]>dfn[lca]) 
				storage(sta[top-1],sta[top]),top--;
				if(sta[top-1]!=lca)
				{
					link[lca]=0;
					storage(lca,sta[top--]);
					sta[++top]=lca;
				}
				else  storage(lca,sta[top--]);
			}
			link[h[i]]=0;
			sta[++top]=h[i];
		}
		for(int i=1;i<top;i++)
		storage(sta[i],sta[i+1]);
		tree_dp(1);
		Rotate(1);
	}
}
namespace Tree2
{
	struct edge
	{
		int y,next;
		int v;
	}e[2*N];
	int link[N],t=0;
	inline void add(int x,int y,int v)
	{
		e[++t].y=y;
		e[t].v=v;
		e[t].next=link[x];
		link[x]=t;
	}	
	LL dis[N];
	int siz[N],son[N];
	bool vis[N];
	void getroot(int x,int pre,int &root,int tot)
	{
		siz[x]=1;son[x]=0;
		for(int i=link[x];i;i=e[i].next)
		{
			int y=e[i].y;
			if(y==pre||vis[y])continue;
			getroot(y,x,root,tot);
			siz[x]+=siz[y];
			son[x]=max(son[x],siz[y]);
		}
		son[x]=max(son[x],tot-siz[x]);
		if(!root||son[x]<son[root])root=x;
	}
	void Extend(int x,int pre)
	{
		siz[x]=1;
		h[++K]=x;
		E[x]=dis[x];
		key[x]=1;
		for(int i=link[x];i;i=e[i].next)
		{
			int y=e[i].y;
			if(vis[y]||y==pre)continue;
			dis[y]=dis[x]+e[i].v;
			Extend(y,x);
			siz[x]+=siz[y];
		}
	}
	void Divide(int x)
	{
		vis[x]=1;
		dis[x]=0;
		K=0;
		Extend(x,0);
		Tree1::Build();
		for(int i=1;i<=K;i++)
		key[h[i]]=0;
		for(int i=link[x];i;i=e[i].next)
		{
			int y=e[i].y;
			if(vis[y])continue;
			int z=0;
			getroot(y,x,z,siz[y]);
			Divide(z);
		}
	}
	void Init()
	{
		for(int i=1;i<n;i++)
		{
			int x,y,v;
			read(x);read(y);read(v);
			add(x,y,v);
			add(y,x,v);
		}
		int rt=0;
		getroot(1,0,rt,n);
		Divide(rt);
	}
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	ans[i]=1e18;
	Tree1::init();
	Tree2::Init();
	for(int i=1;i<=n;i++)
	printf("%lld\n",ans[i]);
	return 0;
}

详细

Test #1:

score: 0
Runtime Error

input:

250000
137466 116241 624409157
188961 163586 148491970
13958 122239 46409636
186120 44010 919858866
72320 102560 92679302
158544 236582 882613876
22331 114267 646741536
210782 42861 679450428
56693 45397 898958944
71188 114724 904191407
15203 225401 210626781
31071 144225 278121829
110354 83972 4557...

output:


result: