P2634 [国家集训队]聪聪可可

题目描述

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

他们的爸爸快被他们的争吵烦死了,所以他发明了一个新游戏:由爸爸在纸上画n个“点”,并用n-1条“边”把这n个“点”恰好连通(其实这就是一棵树)。并且每条“边”上都有一个数。接下来由聪聪和可可分别随即选一个点(当然他们选点时是看不到这棵树的),如果两个点之间所有边上数的和加起来恰好是3的倍数,则判聪聪赢,否则可可赢。

聪聪非常爱思考问题,在每次游戏后都会仔细研究这棵树,希望知道对于这张图自己的获胜概率是多少。现请你帮忙求出这个值以验证聪聪的答案是否正确。

输入格式

输入的第1行包含1个正整数n。后面n-1行,每行3个整数x、y、w,表示x号点和y号点之间有一条边,上面的数是w。

输出格式

以即约分数形式输出这个概率(即“a/b”的形式,其中a和b必须互质。如果概率为1,输出“1/1”)。

输入输出样例

输入 #1复制

  1. 5
  2. 1 2 1
  3. 1 3 2
  4. 1 4 1
  5. 2 5 3
输出 #1复制

  1. 13/25

说明/提示

【样例说明】

13组点对分别是(1,1) (2,2) (2,3) (2,5) (3,2) (3,3) (3,4) (3,5) (4,3) (4,4) (5,2) (5,3) (5,5)。

【数据规模】

对于100%的数据,n<=20000。

sol:树形dp即可,也可以点分(很久前写的(大雾,dp[i][j]表示以i为根的子树中到i的和%i=j的个数

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef int ll;
  4. inline ll read()
  5. {
  6. ll s=; bool f=; char ch=' ';
  7. while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
  8. while(isdigit(ch)) {s=(s<<)+(s<<)+(ch^); ch=getchar();}
  9. return (f)?(-s):(s);
  10. }
  11. #define R(x) x=read()
  12. inline void write(ll x)
  13. {
  14. if(x<) {putchar('-'); x=-x;}
  15. if(x<) {putchar(x+''); return;}
  16. write(x/); putchar((x%)+'');
  17. }
  18. #define W(x) write(x),putchar(' ')
  19. #define Wl(x) write(x),putchar('\n')
  20. const int N=,M=;
  21. int n,dp[N][],ans=;
  22. int tot=,Next[M],to[M],val[M],head[N];
  23. inline void Link(int x,int y,int z){Next[++tot]=head[x]; to[tot]=y; val[tot]=z; head[x]=tot;}
  24. inline void dfs(int x,int fat)
  25. {
  26. int e,i,j;
  27. dp[x][]=; dp[x][]=dp[x][]=;
  28. for(e=head[x];e;e=Next[e]) if(to[e]!=fat)
  29. {
  30. dfs(to[e],x);
  31. for(i=;i<;i++)
  32. {
  33. ans+=dp[x][i]*dp[to[e]][(-i-val[e])%]*;
  34. }
  35. for(i=;i<;i++)
  36. {
  37. dp[x][(i+val[e])%]+=dp[to[e]][i];
  38. }
  39. }
  40. // cout<<x<<' '<<dp[x][0]<<' '<<dp[x][1]<<' '<<dp[x][2]<<endl;
  41. }
  42. int main()
  43. {
  44. int i,x,y,z;
  45. R(n);
  46. for(i=;i<n;i++)
  47. {
  48. R(x); R(y); z=read()%; Link(x,y,z); Link(y,x,z);
  49. }
  50. dfs(,);
  51. ans+=n;
  52. int gg=__gcd(n*n,ans);
  53. write(ans/gg); putchar('/'); Wl(n*n/gg);
  54. return ;
  55. }
  56. /*
  57. input
  58. 5
  59. 1 2 1
  60. 1 3 2
  61. 1 4 1
  62. 2 5 3
  63. output
  64. 13/25
  65. */
  1. #include <cstdio>
  2. #include <algorithm>
  3. using namespace std;
  4. const int N=,M=,inf=0x3f3f3f3f;
  5. int n,re=,tot=,Next[M],to[M],val[M],head[M],rt,sum,sz[N],pp[N],arr[N],tong[],gg;
  6. inline void add(int x,int y,int z){Next[++tot]=head[x];to[tot]=y;val[tot]=z;head[x]=tot;}
  7. inline int gcd(int x,int y){return (y==)?x:gcd(y,x%y);}
  8. inline void getrt(int x,int fa)
  9. {
  10. int i; sz[x]=; pp[x]=;
  11. for(i=head[x];i;i=Next[i])
  12. {
  13. if(!arr[to[i]]&&to[i]!=fa){getrt(to[i],x); sz[x]+=sz[to[i]]; pp[x]=max(pp[x],sz[to[i]]);}
  14. }pp[x]=max(pp[x],sum-pp[x]); if(pp[x]<pp[rt])rt=x;
  15. }
  16. inline void dfs(int x,int fa,int pre)
  17. {
  18. tong[pre]++; int i;
  19. for(i=head[x];i;i=Next[i])
  20. {
  21. if(to[i]!=fa&&!arr[to[i]])dfs(to[i],x,(pre+val[i])%);
  22. }
  23. }
  24. inline void calc(int x,int op,int v)
  25. {
  26. tong[]=tong[]=tong[]=; dfs(x,,v%); re+=op*(*tong[]*tong[]+tong[]*tong[]+tong[]+tong[]);
  27. }
  28. inline void solve(int x)
  29. {
  30. int i; arr[x]=; calc(x,,);
  31. for(i=head[x];i;i=Next[i])
  32. {
  33. if(!arr[to[i]])
  34. {
  35. calc(to[i],-,val[i]); sum=sz[to[i]]; pp[rt=]=inf; getrt(to[i],); solve(rt);
  36. }
  37. }
  38. }
  39. int main()
  40. {
  41. int i,x,y,z; scanf("%d",&n); sum=pp[rt=]=n;
  42. for(i=;i<n;i++)
  43. {
  44. scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z);
  45. }getrt(,); solve(rt); gg=gcd(re,n*n); printf("%d/%d\n",re/gg,n*n/gg);
  46. }

点分

luogu2634的更多相关文章

  1. luogu2634 聪聪可可 (树形dp)

    要求出两点间距离==0(mod3) 的数量,然后除以(n*n) 设f[i][j]为i的子树到i的距离==j(mod3)的数量,然后做树形dp即可 因为要最简,所以要求一下gcd,然后除下去 #incl ...

  2. luogu2634 聪聪可可

    点分治裸题 #include <iostream> #include <cstdio> using namespace std; int n, uu, vv, ww, ans, ...

随机推荐

  1. 【AC自动机】玄武密码

    [题目链接] https://loj.ac/problem/10058 [题意] 对于每一段文字,其前缀在母串上的最大匹配长度是多少呢 [参考别人的题解] https://www.luogu.org/ ...

  2. 作业12:List集合类

    一 为什么使用List? 1 List与数组 List 数组 可变长度 固定长度 方便的接口(支持Java8的Stream) / 2 List的实现方式 数组:ArrayList 查询效率比较高 插入 ...

  3. Python的.sort()方法和sorted()比较总结

    1,.sort()方法 使用方式是:列表.sort(),作用是将原来的列表正序排序,所以它是对原来的列表进行的操作,不会产生一个新列表,例如: import random numList=[] pri ...

  4. .net core 根据数据库生成实体类

    微软最近几年在跨平台上不断发力,很多.net程序员也摩拳擦掌,对微软寄以厚望.就在最近,微软还推出了asp .net core2.0预览版. 通过对.net core的简单尝试,我发现以往我们开发MV ...

  5. RestShrap Simple REST and HTTP Client for .NET 了解

    最近做一个项目,需要上传文件到文件服务器, 文件服务器是 内部的webapi形式的接口.经朋友推荐使用restshrap , 例子: //上传文件 var request=new RestClient ...

  6. android项目笔记整理(2)

    31.利用SharedPreferences存储时间     读取时间:     SharedPreferences sp=this.getSharedPreferences("actm&q ...

  7. PHP中pdo的使用

    <?php /** *下面代码中information为表名 * */ //1.先要连数据库 $pdo=new PDO('mysql:host=localhost;dbname=数据库名','用 ...

  8. 学习笔记:安装swig+用SWIG封装C++为Python模块+SWIG使用说明

    这段时间一直在摸索swing,用它来封装C++代码来生成python脚步语言.并总结了swing从安装到配置再到代码封装编译生成动态库的整个过程,下面这篇文章都是我在实际的运用中的一些经验总结,分享给 ...

  9. [Abp vNext微服务实践] - 添加中文语言

    简介 abp vNext中提供了多语言功能,默认语言是英文,没有提供中文语言包.在业务开发中,定义权限后需要用中文的备注提供角色选择,本篇将介绍如何在abp vNext中加入中文语言. step1:添 ...

  10. ACM算法模板整理

    史诗级ACM模板整理 基本语法 字符串函数 istream& getline (char* s, streamsize n ); istream& getline (char* s, ...