100pts 求助
查看原帖
100pts 求助
648933
HarmonicQuadrilatera楼主2023/8/21 10:13

虽然过了,但用时 1.99s 比平均速度慢二十被,喜提最裂解。我的点分治哪里慢了?

#include<bits/stdc++.h>
#define N 20000
#define EL(x,y,z) ((el){(x),(y),(z)})
using namespace std;
struct el{
	int x,y,z;
	inline void ad(){x++;}
	el operator +(el a)
	{return EL(x+a.x,y+a.y,z+a.z);}
	inline void debug()
	{printf("[%d %d %d]\n",x,y,z);}
};
struct ljb{
	int en,v[2*N+5],w[2*N+5],fst[N+5],nxt[2*N+5];
	inline void add(int x,int y,int z)
	{
		en++;
		v[en]=y;
		w[en]=z;
		nxt[en]=fst[x];
		fst[x]=en;
	}
};
ljb g;
bool vis[N+5];
int n,sz[N+5];
//树的重心
inline int zzp_gets_cxc(int x,int f,int sum)
{
	sz[x]=1;
	int res=0;
	for(int i=g.fst[x];i;i=g.nxt[i])
		if(g.v[i]!=f&&!vis[g.v[i]])
		{
			res=max(res,zzp_gets_cxc(g.v[i],x,sum));
			sz[x]+=sz[g.v[i]];
		}
	if(sz[x]>=sum/2) return x;
	return res;
}
inline el getel(int x,int f,int z)
{
	el res=EL(0,0,0);
	if(z%3==0) res.x++;
	if(z%3==1) res.y++;
	if(z%3==2) res.z++;
	for(int i=g.fst[x];i;i=g.nxt[i])
		if(g.v[i]!=f&&!vis[g.v[i]])
			res=res+getel(g.v[i],x,z+g.w[i]);
	return res;
}
inline int dfs(int x,int f)
{
//	cout<<'('<<x<<"):\n";
	vis[x]=1;
	int res=0;
	el tot=EL(0,0,0);
	for(int i=g.fst[x];i;i=g.nxt[i])
		if(g.v[i]!=f&&!vis[g.v[i]])
		{
			int v=g.v[i];
			el now=getel(v,x,g.w[i]);
			res+=now.x+now.x*tot.x+now.y*tot.z+now.z*tot.y;
			tot=tot+now;
		//	tot.debug();
		}
	for(int i=g.fst[x];i;i=g.nxt[i])
		if(g.v[i]!=f&&!vis[g.v[i]])
		{
			int v=g.v[i];
			int r=zzp_gets_cxc(v,x,sz[v]);
			zzp_gets_cxc(r,0,sz[v]);
			res+=dfs(r,x);
		}
	return res;
}
inline int gcd(int x,int y)
{
	if(y==0) return x;
	return gcd(y,x%y);
}
int main()
{
	cin>>n;
	for(int i=1;i<n;i++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		g.add(x,y,z);
		g.add(y,x,z);
	}
//	cout<<zzp_gets_cxc(1,0,n);
	int ans=2*dfs(zzp_gets_cxc(1,0,n),0)+n;
	cout<<ans/gcd(ans,n*n)<<'/'<<n*n/gcd(ans,n*n);
	return 0;
}

记录

2023/8/21 10:13
加载中...