洛谷 P2634 [国家集训队]聪聪可可-树分治(点分治,容斥版) +读入挂+手动O2优化吸点氧才过。。。-树上路径为3的倍数的路径数量

时间:2022-12-23 11:08:32

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复制
5
1 2 1
1 3 2
1 4 1
2 5 3
输出 #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。

题意就是找树上任意两点路径为3的倍数的路径数,除以所有路径数。

点分治,最后两组数据怎么也过不了,今天过了。

换了个读入挂,也不行,手动吸氧过了。

不知道为什么老是超时,有点躁。

关于C++手动开O2优化:

  • O2优化能使程序的编译效率大大提升

  • 从而减少程序的运行时间,达到优化的效果。

  • C++程序中的O2开关如下所示:

  • #pragma GCC optimize(2)
  • 只需将这句话放到程序的开头即可打开O2优化开关。

一开始手动吸氧也没过,后来可能网络稳了,试了很多次都过了。

代码:

 //点分治
#include<bits/stdc++.h>
using namespace std;
#define fin freopen("in.txt", "r", stdin)
#define fout freopen("out.txt", "w", stdout)
#define FI(n) FastIO::read(n)
#pragma GCC optimize(2)//O2优化,手动吸氧才过。。。
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=2e4+;
const int maxm=1e7+;
const int mod=; int head[maxn<<],tot;
int root,allnode,n,m,k;
int vis[maxn],dis[maxn],siz[maxn],maxv[maxn];//maxv为重心节点
int ans[maxn];
ll sum=; //namespace IO{
// char buf[1<<15],*S,*T;
// inline char gc(){
// if (S==T){
// T=(S=buf)+fread(buf,1,1<<15,stdin);
// if (S==T)return EOF;
// }
// return *S++;
// }
// inline int read(){
// int x; bool f; char c;
// for(f=0;(c=gc())<'0'||c>'9';f=c=='-');
// for(x=c^'0';(c=gc())>='0'&&c<='9';x=(x<<3)+(x<<1)+(c^'0'));
// return f?-x:x;
// }
// inline long long readll(){
// long long x;bool f;char c;
// for(f=0;(c=gc())<'0'||c>'9';f=c=='-');
// for(x=c^'0';(c=gc())>='0'&&c<='9';x=(x<<3)+(x<<1)+(c^'0'));
// return f?-x:x;
// }
//}
//using IO::read;
//using IO::readll; namespace FastIO {//读入挂
const int SIZE = << ;
char buf[SIZE], obuf[SIZE], str[];
int bi = SIZE, bn = SIZE, opt;
int read(char *s) {
while (bn) {
for (; bi < bn && buf[bi] <= ' '; bi++);
if (bi < bn) break;
bn = fread(buf, , SIZE, stdin);
bi = ;
}
int sn = ;
while (bn) {
for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
if (bi < bn) break;
bn = fread(buf, , SIZE, stdin);
bi = ;
}
s[sn] = ;
return sn;
}
bool read(int& x) {
int n = read(str), bf; if (!n) return ;
int i = ; if (str[i] == '-') bf = -, i++; else bf = ;
for (x = ; i < n; i++) x = x * + str[i] - '';
if (bf < ) x = -x;
return ;
}
}; ll gcd(ll a,ll b)
{
return b==?a:gcd(b,a%b);
} struct node{
int to,next,val;
}edge[maxn<<]; void add(int u,int v,int w)//前向星存图
{
edge[tot].to=v;
edge[tot].next=head[u];
edge[tot].val=w;
head[u]=tot++;
} void init()//初始化
{
memset(head,-,sizeof head);
memset(vis,,sizeof vis);
tot=;
} void get_root(int u,int father)//求重心
{
siz[u]=;maxv[u]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v==father||vis[v]) continue;
get_root(v,u);
siz[u]+=siz[v];
maxv[u]=max(maxv[u],siz[v]);
}
maxv[u]=max(maxv[u],allnode-siz[u]);//保存节点size
if(maxv[u]<maxv[root]) root=u;//更新保存当前子树的重心
} void get_dis(int u,int father)//获取子树所有节点与根的距离
{
ans[dis[u]%mod]++;//保存数量
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v==father||vis[v]) continue;
int w=edge[i].val;
dis[v]=(dis[u]+w)%mod;
get_dis(v,u);
}
} ll cal(int u,int now)//每一棵子树的计算
{
ans[]=ans[]=ans[]=;
dis[u]=now;
get_dis(u,);
ll ret=ans[]*ans[]*+ans[]*(ans[]-)+ans[];//1的加上2的+0的
return ret;
} void solve(int u)
{
sum+=cal(u,);//所有满足的
vis[u]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
int w=edge[i].val;
if(vis[v]) continue;
sum-=cal(v,w);//去掉子树的,容斥思想。
allnode=siz[v];
root=;
get_root(v,u);
solve(root);
}
} int main()
{
// n=read();
FI(n);
init();
for(int i=;i<n;i++){
int u,v,w;
FI(u),FI(v),FI(w);
add(u,v,w);
add(v,u,w);
}
root=;allnode=n;maxv[]=inf;
get_root(,);
solve(root);
ll num=n*n;
ll GCD=gcd(sum,num);
printf("%lld/%lld\n",sum/GCD,num/GCD);
}

洛谷 P2634 [国家集训队]聪聪可可-树分治(点分治,容斥版) +读入挂+手动O2优化吸点氧才过。。。-树上路径为3的倍数的路径数量的更多相关文章

  1. 模板—点分治A(容斥)(洛谷P2634 &lbrack;国家集训队&rsqb;聪聪可可)

    洛谷P2634 [国家集训队]聪聪可可 静态点分治 一开始还以为要把分治树建出来……• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法.• A:朴素做法,直接找重心, ...

  2. 洛谷 P2634 &lbrack;国家集训队&rsqb;聪聪可可 解题报告

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

  3. 洛谷P2634 &lbrack;国家集训队&rsqb;聪聪可可 (点分治)

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

  4. 洛谷-P2634 &lbrack;国家集训队&rsqb;聪聪可可 点分治

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

  5. 洛谷P2634 &lbrack;国家集训队&rsqb;聪聪可可&lpar;点分治&rpar;

    传送门 题意: 给出一颗树,每条边都有一定的边权. 先问点之间路径和为\(3\)的倍数的点对有多少. 思路: 点分治模板题. 可以将问题转化为经过一个点\(t\)的路径和不经过点\(t\)的路径两种情 ...

  6. &lbrack;洛谷P2634&rsqb;&lbrack;国家集训队&rsqb;聪聪可可

    题目大意:给你一棵树,随机选两个点,求它们之间路径长度是$3$的倍数的概率 题解:点分治,求出当前状态的重心,然后求出经过重心的答案,接着分治每棵子树.注意考虑重复计算的情况 卡点:无 C++ Cod ...

  7. 洛谷 P2634 &lbrack;国家集训队&rsqb;聪聪可可

    点分板子2333 注释都是错过的地方 #include<cstdio> #include<algorithm> using namespace std; typedef lon ...

  8. 洛谷P2634 &lbrack;国家集训队&rsqb;聪聪可可 点分治模板

    题意 在一棵树上任意选两个点,求它们距离模3为0的概率. 分析 树分治模板 Code #include<bits/stdc++.h> #define fi first #define se ...

  9. &lbrack;洛谷P1527&rsqb; &lbrack;国家集训队&rsqb;矩阵乘法

    洛谷题目链接:[国家集训队]矩阵乘法 题目背景 原 <补丁VS错误>请前往P2761 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入 ...

随机推荐

  1. js动态获取子复选项并设计全选及提交

    在做项目的时候,会遇到根据父选项,动态的获取子选项,并列出多个复选框,提交时,把选中的合并成一个字符提交后台 本章将讲述如何通过js控制实现该操作: 1:设计父类别为radio,为每一个radio都加 ...

  2. Imperva WAF使用笔记

    添加IP白名单 在对自己公司网站进行安全测试时会被WAF拦截,如果把WAF彻底停掉就无法拦截到外部的攻击了. 此时可以添加IP地址白名单,白名单内的IP对网站发起扫描时不会做拦截.

  3. hdu 4635 强连通度缩点

    思路:想用Tarjan算法进行缩点,并记录每个连通分支的点数.缩点完毕过后,找出所有出度或入度为0的连通分量,假设该连通分量的点数为num[i],那么 ans=Max(ans,(n-num-1)*(n ...

  4. 对有状态bean和无状态bean的理解(转)

    现实中,很多朋友对两种session bean存在误解,认为有状态是实例一直存在,保存每次调用后的状态,并对下一次调用起作用,而认为无状态是每次调用实例化一次,不保留用户信息.仔细分析并用实践检验后, ...

  5. tar、zip 、unzip 打包与压缩 &lpar;参考:http&colon;&sol;&sol;pengyl&period;blog&period;51cto&period;com&sol;5591604&sol;1191197&rpar;

    通常都是先通过tar命令将多个文件或目录打包成一个包文件,然后再通过gzip或bzip2进行压缩,如*.tar.gz和*.tar.bz2就属于这种先打包再压缩的文件.在实际使用中,一般都是通过tar命 ...

  6. 算法-最长子序列和C&sol;C&plus;&plus;实现(三个复杂度)

    最长子序列和的问题非常easy: 就是一个数组,求出当中当中连续的某一段和,而这一段和是全部的连续段和的最大的值.求出这个值. 先说复杂度最高的:O(n3) 直接上代码,非常easy的: // // ...

  7. Cocos2d-x 3&period;0final 终结者系列教程04-引擎架构分析

    从前,有一个跟我来Android学生,总是问我: 沉老师,为什么Android的形式被称为Activity,为什么要onCreate方法写setContentView(R.layout.main)? ...

  8. 很简单的Java断点续传实现原理

    原理解析 在开发当中,"断点续传"这种功能很实用和常见,听上去也是比较有"逼格"的感觉.所以通常我们都有兴趣去研究研究这种功能是如何实现的? 以Java来说,网 ...

  9. 安装Linux内核源代码

    系统:Ubuntu 18 CPU架构:AMD64 1,在终端输入:sudo apt install linux-source 命令 2,进入/usr/src/linux-source-4.15.0目录 ...

  10. C&num; Lambda 表达式学习之(四):动态构建类似于 c &equals;&gt&semi; c&period;Age &equals;&equals; 2 &vert;&vert; c&period;Age &equals;&equals; 5 &vert;&vert; c &equals;&gt&semi; c&period;Age &equals;&equals; 17 等等一个或多个 OrElse 的表达式

    可能你还感兴趣: 1. C# Lambda 表达式学习之(一):得到一个类的字段(Field)或属性(Property)名,强类型得到 2. C# Lambda 表达式学习之(二):LambdaExp ...