求助,为啥我跑的这么慢...
查看原帖
求助,为啥我跑的这么慢...
341373
Autofreeze楼主2021/1/25 15:11

RT,我看别人都是 100ms- 就过了的,我这个不开 O2 会 T ,开了也要1s+才能过,是常数问题吗?怎么优化啊,自己算了算觉得复杂度好像没啥问题...(因为怕算错所以删除线)

#include<bits/stdc++.h>
#define re register
#define N 201001
#define MAX 2001
#define inf 1e18
#define eps 1e-10
using namespace std;
typedef long long ll;
typedef double db;
inline void read(re ll &ret)
{
    ret=0;re ll pd=0;re char c=getchar();
    while(!isdigit(c)){pd|=c=='-';c=getchar();}
    while(isdigit(c)){ret=(ret<<1)+(ret<<3)+(c^48);c=getchar();}
    ret=pd?-ret:ret;
    return;
}
ll n,x,y,w,root,maxn[N],num,siz[N],all,ans;
vector<pair<ll,ll> >v[N];
bool vis[N];
inline void find(re ll ver,re ll fa)
{
	siz[ver]=1;
	for(re int i=0;i<v[ver].size();i++)
	{
		re ll to=v[ver][i].first;
		if(to==fa||vis[to])
			continue;
		find(to,ver);
		siz[ver]+=siz[to];
		maxn[ver]=max(maxn[ver],siz[to]);
	}
	maxn[ver]=max(maxn[ver],num-siz[ver]);
	if(maxn[ver]<maxn[root])
		root=ver;
	return;
}
ll val[3],dis[3];
inline void getdis(re ll ver,re ll fa,re ll d)
{
	dis[d%3]++;
	for(re int i=0;i<v[ver].size();i++)
	{
		re ll to=v[ver][i].first,dd=v[ver][i].second;
		if(to==fa||vis[to])
			continue;
		getdis(to,ver,d+dd);
	}
	return;
}
inline void solve(re ll ver)
{
	memset(val,0,sizeof(val));
	val[0]=1;
	ans++;
	for(re int i=0;i<v[ver].size();i++)
	{
		re ll to=v[ver][i].first,d=v[ver][i].second;
		if(vis[to])
			continue;
		memset(dis,0,sizeof(dis));
		getdis(to,ver,d);
		ans+=(val[0]*dis[0]+val[1]*dis[2]+val[2]*dis[1])<<1;
		for(re int j=0;j<3;j++)
			val[j]+=dis[j];
	}
	return;
}
inline void divide(re ll ver)
{
	if(vis[ver])
		return;
	vis[ver]=true;
	solve(ver);
	for(re int i=0;i<v[ver].size();i++)
	{
		re ll to=v[ver][i].first;
		if(vis[to])
			continue;
		num=siz[to];
		root=0;
		maxn[0]=inf;
		find(to,ver);
		divide(root);
	}
	return;
}
inline ll gcd(re ll a,re ll b)
{
	if(!b)
		return a;
	return gcd(b,a%b);
}
signed main()
{
//	freopen("P2634_9.in","r",stdin);
	read(n);
	all=n*n;
	for(re int i=1;i<n;i++)
	{
		read(x);
		read(y);
		read(w);
		v[x].push_back(make_pair(y,w));
		v[y].push_back(make_pair(x,w));
	}
	maxn[0]=inf;
	num=n;
	find(1,0);
	divide(root);
	re ll now=gcd(ans,all);
	ans/=now,all/=now;
	printf("%lld/%lld\n",ans,all);
	exit(0);
}
2021/1/25 15:11
加载中...