bzoj传送门

luogu传送门

这题算是很sb的点分治了,最近在点分治复习,写了练练手,对于这个题只需要对统计0,1,2出现的次数就好了吧,然后发现答案不对,也就是每个点对需要算两遍嘛,0也算,所以答案再加个n就好啦

(用树状数组的\(O(nlog^2)\))代码:

#include<cstdio>
#define max(a,b) (a>b?a:b)
int ans,rt,sum,w,size[20001],f[4],son[20001],dis[20001],n,pre[40001],nxt[40001],h[20001],v[40001],cnt;
bool vis[20001];
void add(int x,int y,int z)
{
pre[++cnt]=y;nxt[cnt]=h[x];h[x]=cnt;v[cnt]=z;
pre[++cnt]=x;nxt[cnt]=h[y];h[y]=cnt;v[cnt]=z;
}
void getroot(int x,int fa)
{
size[x]=1;son[x]=0;
for(int i=h[x];i;i=nxt[i])
if(pre[i]!=fa&&!vis[pre[i]])
{
getroot(pre[i],x);
size[x]+=size[pre[i]];
son[x]=max(size[pre[i]],son[x]);
}
son[x]=max(son[x],sum-size[x]);
if(son[x]<son[rt])rt=x;
}
void getans(int x,int fa)
{
if(dis[x]!=0)ans+=f[3-dis[x]];
else ans+=f[0]+1;
for(int i=h[x];i;i=nxt[i])
if(!vis[pre[i]]&&pre[i]!=fa)
{
dis[pre[i]]=(dis[x]+v[i])%3;
getans(pre[i],x);
}
}
void getdeep(int x,int fa)
{
f[dis[x]]++;
for(int i=h[x];i;i=nxt[i])if(!vis[pre[i]]&&pre[i]!=fa)getdeep(pre[i],x);
}
void dfs(int x)
{
vis[x]=1;
for(int i=h[x];i;i=nxt[i])
if(!vis[pre[i]])
{
dis[pre[i]]=v[i]%3;
getans(pre[i],0),getdeep(pre[i],0);
}
f[0]=f[1]=f[2]=0;
for(int i=h[x];i;i=nxt[i])
if(!vis[pre[i]])
{
rt=0;sum=size[pre[i]];getroot(pre[i],0);
dfs(rt);
}
}
int gcd(int a,int b)
{
if(!b)return a;
return gcd(b,a%b);
}
int main()
{
scanf("%d",&n);
for(int i=1,x,y,z;i<n;i++)scanf("%d%d%d",&x,&y,&z),add(x,y,z);
sum=son[0]=n;getroot(1,0);dfs(rt);
ans=ans*2+n;w=n*n;
printf("%d/%d\n",ans/gcd(ans,w),w/gcd(ans,w));
}

(当年写的two pointer(也称尺取法)):

#include<cstdio>
#include<algorithm>
using namespace std;
int now,st[20001],n,cnt,sum,ans,pre[40001],rt,nxt[40001],v[40001],h[20001],son[20001],size[20001],dis[20001],t[3];
bool vis[20001];
void read(int &x)
{
int f=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
void add(int x,int y,int z)
{
pre[++cnt]=y;nxt[cnt]=h[x];h[x]=cnt,v[cnt]=z;
pre[++cnt]=x;nxt[cnt]=h[y];h[y]=cnt,v[cnt]=z;
}
void getroot(int x,int fa)
{
size[x]=1;son[x]=0;
for(int i=h[x];i;i=nxt[i])
if(!vis[pre[i]]&&pre[i]!=fa)
{
getroot(pre[i],x);
size[x]+=size[pre[i]];
son[x]=max(son[x],size[pre[i]]);
}
son[x]=max(son[x],sum-size[x]);
if(son[x]<son[rt])rt=x;
}
void get(int x,int fa)
{
t[dis[x]%3]++;
for(int i=h[x];i;i=nxt[i])
if(!vis[pre[i]]&&pre[i]!=fa)
{
dis[pre[i]]=dis[x]+v[i];
get(pre[i],x);
}
}
int getans(int x)
{
now=0;
get(x,0);
return t[0]*t[0]+t[1]*t[2]*2;
}
void dfs(int x)
{
vis[x]=1;dis[x]=0;
ans+=getans(x);
t[0]=t[1]=t[2]=0;
for(int i=h[x];i;i=nxt[i])
if(!vis[pre[i]])
{
dis[pre[i]]=v[i];
ans-=getans(pre[i]);
t[0]=t[1]=t[2]=0;
rt=0;sum=size[pre[i]];
getroot(pre[i],0);
dfs(rt);
}
}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int main()
{
read(n);
for(int i=1,x,y,z;i<n;i++)
read(x),read(y),read(z),add(x,y,z);
sum=n;son[0]=n;
getroot(1,0);
dfs(rt);
int mod=gcd(ans,n*n);
printf("%d/%d",ans/mod,n*n/mod);
}

BZOJ2152聪聪可可的更多相关文章

  1. 【BZOJ2152】聪聪可可(点分治)

    [BZOJ2152]聪聪可可(点分治) 题面 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电 ...

  2. BZOJ2152 [国家集训队] 聪聪可可 [点分治]

    题目传送门 聪聪可可 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 5237  Solved: 2750[Submit][Status][Discuss ...

  3. BZOJ2152 聪聪可可 【点分治】

    BZOJ2152 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)--遇到这种问 ...

  4. 【bzoj2152】聪聪可可 点分治

    [bzoj2152]聪聪可可 2014年9月7日3,5472 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是 ...

  5. BZOJ2152 聪聪可可 (点分治)

    2152: 聪聪可可 题意: 在一棵边带权的树中,问任取两个点,这两个点间的权值和是3的倍数的概率. 思路: 经典的点分治题目. 利用点分治在计算所有路径长度,把路径长度对3取模,用t[0],t[1] ...

  6. [bzoj2152][聪聪和可可] (点分治+概率)

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  7. C++之路进阶——bzoj2152(聪聪可可)

    F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  hyxzc Logout 捐赠本站 Notice:由于本OJ建立在 ...

  8. bzoj2152 聪聪可可

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  9. 【BZOJ2152】聪聪可可

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  10. BZOJ2152[国家集训队]聪聪可可——点分治

    题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...

随机推荐

  1. java的一个简单死锁的例子

    package com.deadlock; /* * 演示死锁:(由毕向东视频所得) * 一种解释:Thread—0拿到lock1锁,Thread—1拿到lock2锁,Thread—0想要lock2锁 ...

  2. sam模板

    SAM模板 struct SAM{ * ; struct node{ node*nxt[],*fail; int len; }; node*root;int cnt; node no[maxn]; n ...

  3. leetcode 790. Domino and Tromino Tiling

    We have two types of tiles: a 2x1 domino shape, and an "L" tromino shape. These shapes may ...

  4. [noip2014day2-T1]无线网路发射器选址

    随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129条东西向街道和129条南北向街道所形成的网格状,并且相邻的平行街道之间 ...

  5. Codeforces Beta Round #88 C. Cycle —— DFS(找环)

    题目链接:http://codeforces.com/problemset/problem/117/C C. Cycle time limit per test 2.5 seconds memory ...

  6. mysql优化20条原则

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据 ...

  7. LDAP解释(转)

    我要着重指出,LDAP是一个数据库,但是又不是一个数据库.说他是数据库,因为他是一个数据存储的东西.但是说他不是数据库,是因为他的作用没有数据库这么强大,而是一个目录. 为了理解,给一个例子就是电话簿 ...

  8. linux应用之php开发环境lamp搭建(centos)

    搭建linux+apache+mysql+php环境   1.安装apache: yum install httpd httpd-devel  启动apache: /etc/init.d/httpd ...

  9. hdu 1205 吃糖果(抽屉原理)

    题意:N种糖果,不能把一样的放在一起吃,即第一次吃一种,下一次吃另一种. 思路:找到个数最多的糖果种类(最大的数目记作 ma,该糖果种类记为a),首先把这n个糖果放到n个抽屉里面,然后把剩余的N-1种 ...

  10. java运行Linux命令

    <%@ page language="java" import="java.util.*,java.io.*" pageEncoding="UT ...