(开头先Orz myh)

原题目:

在人类和跳蚤的战争初期,人们凭借着地理优势占据了上风——即使是最强壮的跳蚤,也无法一下越过那一堵坚固的城墙。

在经历了惨痛的牺牲后,跳蚤国王意识到再这样下去,跳蚤国必败无疑。然而为了震慑跳蚤国的老冤家——猴族,跳蚤国那世界上最跳的坦克只能留在跳蚤国本土,无法派上用场。

于是跳蚤国王决定利用跳蚤国最尖端的技术,创造出最强的跳蚤来挽回败局。

为了避免这样的低级失误,跳蚤国王决定使用机器来帮助他创造跳蚤。他把它拥有的 n 种属性放在了 n 个容器中,然后他使用了n−1 条橡胶软管将这 n 个容器连接成了一个树形结构(即任意两个容器之间有且只有一条简单路径)。

跳蚤国王的机器会使用这样的方式来创造跳蚤:跳蚤国王需要选择两个不同的容器u,v(u≠v),那么机器就会使用 u 到 v 的简单路径上的所有的橡胶软管将这条路上的所有属性汇聚到一起制造跳蚤。注意:这时只有 u 到 v 的简单路径上的橡胶软管被用到了。

每一条橡胶软管都有一个耐久度 wi,跳蚤国王认为一个制造的方案是安全的,当且仅当所有被用到的橡胶软管的耐久度的乘积是完全平方数。

现在,跳蚤国王想要知道有多少种不同的制造方案是安全的。但是因为跳蚤国王日理万机,所以他让你——一个刚刚被抓来的人类俘虏来帮他计算答案。

两个制造方案是不同的当且仅当 u 不同或者 v 不同。

输入格式

第一行两个正整数n(n<=100000),表示容器的数目。

以下n−1行,每行三个正整数u,v,w表示一条软管连接u,v,耐久度为w。

输出格式

输出一行一个整数表示制造方案数。

样例一

input

5

1 2 2

1 3 6

1 4 2

4 5 3

output

4

题目大意就是给你一棵有边权的树,让你求其中有多少个点对路径上的边权积为完全平方数。
一开始看这个一脸不可做啊……树剖也不行,点分治貌似行,但是我不会写啊……(貌似其实也不行)
(高阶百度搜索技巧)
其实当传统做法不行的时候,可以反过来看看题目本身的特殊条件。注意到他要求边权积为完全平方数,可以想到其中每个质因子都出现了偶数次。
考虑用什么办法可以判断某个数出现了偶数次,发现偶数个相同的数异或起来必定是0。
为了避免和其他数重复,可以把每个质数哈希一下(这里我懒了,直接用的rand(),导致分数也是rand(60,100))。
所以问题就转化为了求树上异或和为零的路径的个数。
易得当且仅当两个节点到根节点的异或和相等时它们间路径的异或和为0。
所以就可以直接一次dfs求出了^_^
时间复杂度:O(n)(预处理比较麻烦,貌似很多学长被卡常了)
代码:

 #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
struct edge{
int v,next;
ll w;
}a[];
int n,u,v,tot=,pr=,head[],pri[];
ll w,num[],ans=;
map<ll,ll>pp;
bool isp[];
ll rd(){
return (ll)((ll)(rand())<<)+rand();
}
void getprime(){
for(int i=;i<=;i++){
if(!isp[i])pri[++pr]=i;
for(int j=;j<=pr&&i*pri[j]<=;j++){
isp[i*pri[j]]=;
if(!(i%pri[j]))break;
}
}
for(int i=;i<=pr;i++){
pp[pri[i]]=rd();
}
}
void add(int u,int v,ll w){
a[++tot].v=v;
a[tot].w=w;
a[tot].next=head[u];
head[u]=tot;
}
void dfs(int u,int fa){
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(v==fa)continue;
num[v]=num[u]^a[tmp].w;
dfs(v,u);
}
}
int main(){
memset(head,-,sizeof(head));
memset(isp,,sizeof(isp));
srand(time(NULL));
scanf("%d",&n);
getprime();
for(int i=;i<n;i++){
scanf("%d%d%lld",&u,&v,&w);
int ww=;
for(int j=;j<=pr&&pri[j]*pri[j]<=w;j++){
while(!(w%pri[j])){
w/=pri[j];
ww^=pp[pri[j]];
}
}
if(w!=){
if(!pp[w])pp[w]=rd();
ww^=pp[w];
}
add(u,v,ww);
add(v,u,ww);
}
num[]=;
dfs(,-);
sort(num+,num+n+);
for(int i=,j;i<=n;i=j){
j=i;
while(num[i]==num[j]&&j<=n)j++;
ans+=(ll)(j-i)*(j-i-);
}
printf("%lld",ans);
return ;
}

(GDOI2018模拟九)【UOJ#192】【UR#14】最强跳蚤的更多相关文章

  1. 【uoj#192】[UR #14]最强跳蚤 Hash

    题目描述 给定一棵 $n$ 个点的树,边有边权.求简单路径上的边的乘积为完全平方数的点对 $(x,y)\ ,\ x\ne y$ 的数目. 题解 Hash 一个数是完全平方数,当且仅当每个质因子出现次数 ...

  2. 【胡策篇】题解 (UOJ 192 + CF938G + SPOJ DIVCNT2)

    和泉纱雾与烟花大会 题目来源: UOJ 192 最强跳蚤 (只改了数据范围) 官方题解: 在这里哦~(说的很详细了 我都没啥好说的了) 题目大意: 求树上各边权乘积是完全平方数的路径数量. 这种从\( ...

  3. UOJ#192. 【UR #14】最强跳蚤

    题目链接 http://uoj.ac/problem/192 暑期课第二天 树上问题进阶 具体内容看笔记博客吧 题意 n个节点的树T 边有边权w 求满足(u, v)上所有边权乘积为完全平方数的路径有多 ...

  4. UOJ #192 【UR #14】 最强跳蚤

    题目链接:最强跳蚤 这道题本来不想写博客的--但是鉴于自己犯了低级错误,还是写篇博客记载一下. 一开始我的想法和题解里面的算法而比较类似,也是先分解质因数,然后用质因子是否出现偶数次来判断当前这个数是 ...

  5. [JZOJ5229]【GDOI2018模拟7.14】小奇的糖果

    题目 题目大意 在一个二维的平面上,有一堆有颜色的点,你需要找出一条水平线段,使得这个线段上面(或者是下面)的点的颜色不包含所有的颜色.问点数最大是多少. 思考历程 在一开始,我看错了题目大意. 题目 ...

  6. [Swift通天遁地]九、拔剑吧-(14)创建更美观的景深视差滚动效果

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  7. UOJ 【UR #5】怎样跑得更快

    [UOJ#62]怎样跑得更快 题面 这个题让人有高斯消元的冲动,但肯定是不行的. 这个题算是莫比乌斯反演的一个非常巧妙的应用(不看题解不会做). 套路1: 因为\(b(i)\)能表达成一系列\(x(i ...

  8. [Xcode 实际操作]九、实用进阶-(14)使用富文本CoreText框架创建丰富多彩的文本

    目录:[Swift]Xcode实际操作 本文将演示如何使用富文本CoreText框架创建丰富多彩的文本图形. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] imp ...

  9. UOJ #22 UR #1 外星人

    LINK:#22. UR #1 外星人 给出n个正整数数 一个初值x x要逐个对这些数字取模 问怎样排列使得最终结果最大 使结果最大的方案数又多少种? n<=1000,x<=5000. 考 ...

随机推荐

  1. hdu 3572 Task Schedule【 最大流 】

    求出最大流,再判断是否满流 先不理解为什么要这样建图 后来看了这一篇题解 http://blog.csdn.net/u012350533/article/details/12361003 把0看做源点 ...

  2. 路飞学城Python-Day24(practise)

    本章总结 练习题 什么是C/S架构? C指的是client(客户端软件),S指的是Server(服务端软件)

  3. Python 函数部分练习题

    函 数 基 础 1.写函数,,用户传入修改的文件名,与要修改的内容,执行函数,完成批了修改操作2.写函数,计算传入字符串中[数字].[字母].[空格] 以及 [其他]的个数 3.写函数,判断用户传入的 ...

  4. [HDU1052]Tian Ji -- The Horse Racing(田忌赛马)

    题目大意:田忌赛马问题,给出田忌和齐威王的马的数量$n$和每匹马的速度$v$,求田忌最多赢齐威王多少钱(赢一局得200,输一局扣200,平局不得不扣). 思路:贪心. 1.若田忌最慢的马可以战胜齐王最 ...

  5. [USACO17JAN] Subsequence Reversal序列反转 (dfs+记忆化)

    题目大意:给你一个序列,你可以翻转任意一段子序列一次,求最长不下降子序列长度 tips:子序列可以不连续,但不能破坏在原序列中的顺序 观察数据范围,n<=50,很小,考虑dfs *dfs来跑区间 ...

  6. [luogu4133 BJOI2012] 最多的方案 (计数dp)

    题目描述 第二关和很出名的斐波那契数列有关,地球上的OIer都知道:F1=1, F2=2, Fi = Fi-1 + Fi-2,每一项都可以称为斐波那契数.现在给一个正整数N,它可以写成一些斐波那契数的 ...

  7. Flask-Babel 使用简介(翻译文档)

    最近用flask-bable翻译一个项目,在网站上查找到有一个示例文档,地址:http://translations.readthedocs.io/en/latest/flask-babel.html ...

  8. [剑指offer] 8+9. 跳台阶+变态跳台阶 (递归 时间复杂度)

    跳台阶是斐波那契数列的一个典型应用,其思路如下: # -*- coding:utf-8 -*- class Solution: def __init__(self): self.value=[0]*5 ...

  9. 小学生都能学会的python(深浅拷贝)

    小学生都能学会的python(深浅拷贝) join() 把列表中的每一项用字符串拼接起来 # lst = ["汪峰", "吴君如", "李嘉欣&quo ...

  10. 引入拦截器及swagger支持及解决redis无法初始化问题

    Springboot引入拦截器 自定义的拦截器类 Interceptor package cn.zytao.taosir.auth.config; import javax.annotation.Re ...