【点分治练习题·不虚就是要AK】点分治

不虚就是要AK(czyak.c/.cpp/.pas)  2s 128M  by zhb

czy很火。因为又有人说他虚了。为了证明他不虚,他决定要在这次比赛AK。

现在他正在和别人玩一个游戏:在一棵树上随机取两个点,如果这两个点的距离是4的倍数,那么算czy赢,否则对方赢。现在czy想知道他能获胜的概率。

*最终输出的概率要求分数的分子和分母的和尽量小且非负数

本题多组数据。对于每组数据:

第一行一个数n,表示树上的节点个数

接下来n-1条边a,b,c描述a到b有一条长度为c的路径

当n=0时表示读入结束

数据组数不超过10。无部分分

输入数据

5

1 2 1

1 3 2

1 4 1

2 5 3

0

输出数据

7/25

数据范围

数据点

n的规模

数据组数

随机生成数据

1

200

1

2

200

1

3

200

<=3

4

2000

<=3

5

2000

<=3

6

2000

<=5

7

20000

<=5

8

20000

<=5

9

20000

<=10

10

20000

<=10


这题其实跟找距离=K的点对有多少个是一样的,我们把距离全部不断mod4就可以了。

然后就是点分治。

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 using namespace std;
  7
  8 const int N=20010;
  9 int n,len,ans;
 10 int v[5],t[5],d[N],first[N],mark[N],size[N];
 11 struct node{
 12     int x,y,d,next;
 13 }a[2*N];
 14
 15 void ins(int x,int y,int d)
 16 {
 17     a[++len].x=x;a[len].y=y;a[len].d=d;
 18     a[len].next=first[x];first[x]=len;
 19 }
 20
 21 int gcd(int x,int y)
 22 {
 23     if(y==0) return x;
 24     return gcd(y,x%y);
 25 }
 26
 27 void find_root(int x,int fa,int tot,int &root)
 28 {
 29     size[x]=1;
 30     bool bk=1;
 31     for(int i=first[x];i;i=a[i].next)
 32     {
 33         int y=a[i].y;
 34         if(y==fa || mark[y]) continue;
 35         find_root(y,x,tot,root);
 36         size[x]+=size[y];
 37         if(2*size[y]>tot) bk=0;
 38     }
 39     if(bk && 2*(tot-size[x])<=tot) root=x;
 40 }
 41
 42 void DFS(int x,int fa)
 43 {
 44     int now=((4-d[x])%4+4)%4;
 45     ans+=v[now];
 46     t[d[x]]++;
 47     size[x]=1;
 48     for(int i=first[x];i;i=a[i].next)
 49     {
 50         int y=a[i].y;
 51         if(mark[y] || y==fa) continue;
 52         d[y]=(d[x]+a[i].d)%4;
 53         DFS(y,x);
 54         size[x]+=size[y];
 55     }
 56 }
 57
 58 void dfs(int x,int tot)
 59 {
 60     find_root(x,0,tot,x);
 61
 62     memset(v,0,sizeof(v));
 63     mark[x]=1;d[x]=0;v[0]++;
 64
 65     for(int i=first[x];i;i=a[i].next)
 66     {
 67         int y=a[i].y;
 68         if(mark[y]) continue;
 69         d[y]=d[x]+a[i].d;
 70         memset(t,0,sizeof(t));
 71         DFS(y,x);
 72         for(int j=0;j<4;j++) v[j]+=t[j];
 73     }
 74     for(int i=first[x];i;i=a[i].next)
 75     {
 76         int y=a[i].y;
 77         if(mark[y]) continue;
 78         dfs(y,size[y]);
 79     }
 80 }
 81
 82 int main()
 83 {
 84     freopen("a.in","r",stdin);
 85     // freopen("czyak.in","r",stdin);
 86     // freopen("czyak.out","w",stdout);
 87     while(1)
 88     {
 89         scanf("%d",&n);
 90         if(!n) break;
 91         ans=0;len=0;
 92         memset(mark,0,sizeof(mark));
 93         memset(first,0,sizeof(first));
 94         for(int i=1;i<n;i++)
 95         {
 96             int x,y,d;
 97             scanf("%d%d%d",&x,&y,&d);
 98             d%=4;
 99             ins(x,y,d);
100             ins(y,x,d);
101         }
102         // for(int i=1;i<=len;i+=2) printf("%d --> %d  %d\n",a[i].x,a[i].y,a[i].d);
103         dfs(1,n);
104         int fz=2*ans+n,fm=n*n;
105         int g=gcd(fz,fm);
106         fz/=g;fm/=g;
107         printf("%d/%d\n",fz,fm);
108     }
109     return 0;
110 }

posted @ 2016-11-10 15:49 拦路雨偏似雪花 阅读( ...) 评论( ...) 编辑 收藏

【点分治练习题·不虚就是要AK】点分治相关推荐

  1. C语言分治算法求中位数,【算法复习】分治算法

    Outline 分治思想和递归表达式 大整数乘法 矩阵乘法的Strassen算法 快速傅里叶变化 基于分治的排序 merge-sort排序 快速排序 排序的下界问题 中位数和顺序统计量 最邻近点对 凸 ...

  2. 【WC2018】通道【边分治】【虚树】【树的直径】

    题意:给三棵基于同一点集的带边权的树,边权非负,求两点间三棵树上距离之和的最大值. n≤105n\leq 10^5n≤105 一句话题解:在第一棵树上做边分治,丢到第二棵树上建虚树,在虚树上根据第三棵 ...

  3. 线段树分治 ---- F. Extending Set of Points(线段树分治 + 可撤销并查集)

    题目链接 题目大意: 你有个点集合SSS,每次往集合里面加点或者删点(如果要加的点出现过),如果(x1,y1),(x2,y1),(x1,y2),(x2,y2)(x1,y1),(x2,y1),(x1,y ...

  4. 点分治 + 树状数组 ---- E. Close Vertices(点分治 + 二维数点)

    题目链接 题目大意: 给出一棵树,问有多少条路径权值和不大于www,长度不大于lll 解题思路: 首先树上路径问题大概率就是点分治了 但是我们对于每个路径有两个性质就是(li,wi)(l_i,w_i) ...

  5. java分治_【Java算法】什么是分治算法?

    1.什么是分治算法? 分治法(Divide-and-Conquer)是一种很重要的算法. 分治就是"分而治之"的意思,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子 ...

  6. 【cdq分治】cdq分治与整体二分学习笔记Part2.cdq分治

    上午的学习学会了整体二分,下午学了cdq分治 发现了二者的区别: 整体二分的主体是在不断地二分答案(把所有询问二分),而cdq分治则是在不断地二分操作. 当然同样的,cdq分治的复杂度也是与区间长度正 ...

  7. 递归与分治java策略实验报告_递归与分治策略–计算机算法设计与分析

    递归概念:直接或者间接调用自身的算法,称为递归运算. 分治思想:把一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相等,递归解决子问题后再将结果合并 下方为一些应用函数.因为 ...

  8. [WC2018]通道——边分治+虚树+树形DP

    题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...

  9. LOJ 2339 「WC2018」通道——边分治+虚树

    题目:https://loj.ac/problem/2339 两棵树的话,可以用 CTSC2018 暴力写挂的方法,边分治+虚树.O(nlogn). 考虑怎么在这个方法上再加一棵树.发现很难弄. 看了 ...

最新文章

  1. 【C++】 64_C++中的异常处理 (上)
  2. 【Java Web开发指南】Java插入中文到数据库中文变成问号解决
  3. oracle的那些事
  4. mysql建表的auto_increment_koa2+koa+mysql快速搭建nodejs服务器
  5. HDU3509(构造矩阵)
  6. 关于python中excel写入案例
  7. Convolutional Neural Networks for Sentence Classification-学习笔记
  8. canvas 平滑运动_什么是电视上的运动平滑?人们为什么讨厌它?
  9. jquery和easui学习总结_jQuery EasyUI总结
  10. 超过8000星的「机器学习路线图」,福利。
  11. linux自动化处理excel,将ansible执行结果进行处理,变成excel,ansibleexcel
  12. 【每日算法Day 84】面试必考题:Trie(字典树/前缀树)的实现
  13. 中概股“回A”政策趋紧 霞客环保终止卖壳
  14. Atitit 身份证与银行卡校验规则
  15. 什么是面形误差PVr?【光学测量、光学设计必看】
  16. Error while obtaining start requests
  17. 页面停留长时间不操作,一定时间退出系统
  18. 【面试相关】202006面试总结
  19. linux去除pdf页头,删除PDF水印小妙招
  20. 以mysql为例有几种隔离级别_mysql有几种隔离级别

热门文章

  1. windows重启oracle监听口令,oracle_windows下命令启动oracle监听和服务
  2. C#写Hook(SetWindowsHookEx、UnHookWindowsHookEx)使用示例
  3. ABAP-Generate dynpro动态屏幕
  4. 最长回文子序列题解 递归+动态规划
  5. 明日之后对哪些服务器维护,明日之后:服务器崩了?先了解这4个隐藏技巧,学会了你就是大神...
  6. 刺激战场国际服越来越卡,竟是腾讯为了让玩家重回和平精英?
  7. 【PTA】数据结构与算法->6-13 LinkList10-带头结点的单链表逆置【有题解视频,可本地编译器调试】作者 通信DS课程组单位 成都信息工程大学
  8. 读书笔记《谷歌时代的工作方法》
  9. 匡庐奇秀,庐山云雾翠
  10. 首个中文版ChatGPT来了:大模型的中国元“Yuan”