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);
}