bzoj 2152 聪聪可可
Posted jklover
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2152 聪聪可可相关的知识,希望对你有一定的参考价值。
bzoj 2152 聪聪可可
- 类似于点分治板子那道题,但是本题的 (n) 更大,而在模 (3) 意义下计算边权和很小,在计算子树路径时,可以开一个桶 (tot[3]) 记录每个权值的路径条数.
- 合并时就不用枚举路径了,对答案贡献显然直接就是 (2*tot[1]*tot[2]+tot[0]^2).
- 这样做每次合并的时间复杂度为常数级,总时间复杂度为 (O(nlogn)).
- 这个方法(可能?)只对边权和很小的时候适用,每次合并是边权大小的时间复杂度.边权较大时,若用 (map) 代替桶,也会多一个 (log) ,和暴力枚举是同级的.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
int x=0;
bool pos=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch=='-')
pos=0;
for(;isdigit(ch);ch=getchar())
x=x*10+ch-'0';
return pos?x:-x;
}
#define inf 1e9
const int MAXN=2e4+10;
int n;
int cnt=0,head[MAXN],to[MAXN<<1],nx[MAXN<<1],val[MAXN<<1];
ll ans,tot[3];
int stk[MAXN],tp;
int vis[MAXN];
int totsiz,siz[MAXN],sonsiz[MAXN],mi,rt;
inline void addedge(int u,int v,int w)
{
++cnt;
nx[cnt]=head[u];
to[cnt]=v;
val[cnt]=w;
head[u]=cnt;
}
void ins(int u,int v,int w)
{
addedge(u,v,w);
addedge(v,u,w);
}
void getroot(int u,int fa)
{
siz[u]=1;
sonsiz[u]=0;
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(vis[v] || v==fa)
continue;
getroot(v,u);
siz[u]+=siz[v];
if(siz[v]>sonsiz[u])
sonsiz[u]=siz[v];
}
sonsiz[u]=max(sonsiz[u],totsiz-siz[u]);
if(sonsiz[u]<mi)
mi=sonsiz[u],rt=u;
}
void getdis(int u,int fa,int len)
{
++tot[len%3];
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(vis[v] || v==fa)
continue;
getdis(v,u,(len+val[i])%3);
}
}
void solve(int rt,int len,int val)
{
tot[0]=tot[1]=tot[2]=0;
getdis(rt,0,len);
ans+=val*(2*tot[1]*tot[2]+tot[0]*tot[0]);
}
void Divide(int u)
{
vis[u]=1;
solve(u,0,1);
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(vis[v])
continue;
solve(v,val[i],-1);
mi=inf;
totsiz=siz[v];
getroot(v,0);
Divide(rt);
}
}
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
int main()
{
n=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read(),w=read();
ins(u,v,w%3);
}
mi=inf;
totsiz=n;
getroot(1,0);
Divide(1);
ll g=gcd(ans,1LL*n*n);
printf("%lld/%lld
",ans/g,1LL*n*n/g);
return 0;
}
以上是关于bzoj 2152 聪聪可可的主要内容,如果未能解决你的问题,请参考以下文章