520的信心赛——点点玩deeeep
3、点点玩 deeeep(deeeep.cpp)
描述
点点最近迷上了 deeeep(此 de 非彼 de),在研究一个特殊的
最长树链问题(树链即树上的一条路径)。现在一棵树中的每个点
都有一个 deeeep 值(正整数)
,点点想在树中找出最长的树链,使
得这条树链上所有对应点的 deeeep 值的最大公约数大于 1。请求出
这条树链的长度。(巨说这道题很 water!
)
格式
输入格式
第 1 行:整数 n(1 ≤ n ≤ 100000),表示点的个数。
第 2~n 行:每行两个整数 x,y 表示 x 和 y 之间有边,数据保证给
出的是一棵树。
第 n+1 行:n 个整数,依次表示点 1~n 对应的权值(1 ≤ 权值 ≤
1,000,000,000)
。
输出格式输出一个整数,表示这条树链的长度。
样例 1
样例输入 1
4
1 2
1 3
2 4
6 4 5 2
样例输出 1
3
限制
对于 100%的数据 1≤n≤100000,1≤ai≤10^9
Solution:
本题考察搜索+数学。
实际上就是乱写暴力。bfs爆搜能ac,还比正解快,简直鬼畜。
枚举每个约数,保留对应的边,做一次最长路径。因为一个数的约数个数可以保证,所以复杂度符合要求。
看起来10^9很虚,但是我们分解质因数只需要预处理出3*10^4里的质数,实际上只有3000多个,3000*n完全不虚,所以我们可以先将n个数全都分解质因数。
然后我们枚举每个质数,枚举所有包含这些质数的点,看一下这些点在树上能形成的最长的链有多长。具体做法是我们将这些点按照深度从大到小排序,然后更新每个点父亲的子树中到父亲的最长链、次长链分别是多长,乱搞一下就行了。
代码:
bfs玄学比正解快:
/*莫名打的玄学复杂度bfs,结果ac——by 520*/
#include<bits/stdc++.h>
#define il inline
using namespace std;
const int maxn = ;
int maxlen=,rd[maxn],a[maxn];
vector<int>v[maxn];
il int gi()
{
int a=;char x=getchar();bool f=;
while((x<''||x>'')&&x!='-')x=getchar();
if(x=='-')x=getchar(),f=;
while(x>=''&&x<='')a=a*+x-,x=getchar();
return f?-a:a;
}
struct node{
int x;
int len;
int gcd;
};
il void bfs(int x,int len,int gcd)
{
node n1,n2;
queue<node>q;
n1.x=x; n1.len=len; n1.gcd=gcd;
q.push(n1);
while(!q.empty())
{
node n1=q.front(); q.pop();
int nx=n1.x, nlen=n1.len, ngcd=n1.gcd;
maxlen=max(nlen, maxlen);
for(int i=;i<v[nx].size();i++)
{
int next=v[nx][i], usegcd=__gcd(a[next],ngcd);
if(usegcd==){
n2.gcd=a[next]; n2.len=; n2.x=next;
q.push(n2);
}
else{
n2.gcd=usegcd; n2.len=+nlen; n2.x=next;
q.push(n2);
}
}
}
}
int main()
{
freopen("deeeep.in","r",stdin);
freopen("deeeep.out","w",stdout);
int x,y,n=gi(),go=;
for(int i=;i<=n;i++)
{
x=gi(),y=gi();
v[x].push_back(y);
rd[y]++;
}
for(int i=;i<=n;i++)
{
if(rd[i]==)go=i;
a[i]=gi();
}
bfs(go,,a[go]);
printf("%d",maxlen);
return ;
}
正解:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
using namespace std;
int n,m,cnt,ans,tot,mor;
const int maxn=;
int to[maxn<<],nxt[maxn<<],head[maxn],v[maxn],d1[maxn],d2[maxn],p[],fa[maxn],dep[maxn],pri[];
bool np[];
vector<int> s[];
map<int,int> mp;
int rd()
{
int ret=; char gc=getchar();
while(gc<''||gc>'') gc=getchar();
while(gc>=''&&gc<='') ret=ret*+gc-'',gc=getchar();
return ret;
}
void dfs(int x)
{
for(int i=head[x];i!=-;i=nxt[i]) if(to[i]!=fa[x]) fa[to[i]]=x,dep[to[i]]=dep[x]+,dfs(to[i]);
}
bool cmp1(int a,int b)
{
return s[a].size()>s[b].size();
}
bool cmp2(int a,int b)
{
return dep[a]>dep[b];
}
void updata(int a,int b)
{
if(d1[b]>d1[a]) d2[a]=d1[a],d1[a]=d1[b];
else d2[a]=max(d2[a],d1[b]);
}
void add(int a,int b)
{
to[cnt]=b,nxt[cnt]=head[a],head[a]=cnt++;
}
int main()
{
freopen("deeeep.in","r",stdin);
freopen("deeeep.out","w",stdout);
n=rd();
int i,j,a,b;
memset(head,-,sizeof(head));
for(i=;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
for(i=;i<=n;i++) v[i]=rd(),m=max(m,v[i]);
m=ceil(sqrt(1.0*m));
for(i=;i<=m;i++)
{
if(!np[i]) pri[++tot]=i,mp[i]=tot;
for(j=;j<=tot&&i*pri[j]<=m;j++)
{
np[i*pri[j]]=;
if(i%pri[j]==) break;
}
}
dep[]=,dfs(),mor=tot;
for(i=;i<=n;i++)
{
for(j=;j<=tot&&pri[j]*pri[j]<=v[i];j++)
{
if(v[i]%pri[j]==)
{
s[j].push_back(i);
while(v[i]%pri[j]==) v[i]/=pri[j];
}
}
if(v[i]>)
{
if(mp.find(v[i])==mp.end()) mp[v[i]]=++mor;
s[mp[v[i]]].push_back(i);
}
}
ans=;
for(i=;i<=mor;i++) p[i]=i;
sort(p+,p+mor+,cmp1);
for(i=;i<=mor;i++)
{
b=p[i];
if(s[b].size()<=ans) break;
sort(s[b].begin(),s[b].end(),cmp2);
for(j=;j<s[b].size();j++) a=s[b][j],d1[a]++,d2[a]++,ans=max(ans,d1[a]+d2[a]-),updata(fa[a],a);
for(j=;j<s[b].size();j++) a=s[b][j],d1[a]=d2[a]=d1[fa[a]]=d2[fa[a]]=;
}
printf("%d",ans);
return ;
}
520的信心赛——点点玩deeeep的更多相关文章
- 「THP3考前信心赛」解题报告
目录 写在前面&总结: T1 T2 T3 T4 写在前面&总结: \(LuckyBlock\) 良心出题人!暴力分给了 \(120pts\) \(T1\) 貌似是个结论题,最后知道怎么 ...
- 「THP3考前信心赛」题解
目录 写在前面 A 未来宇宙 B 空海澄澈 C 旧约酒馆 算法一 算法二 D 博物之志 算法一 算法二 算法三 写在前面 比赛地址:THP3 考前信心赛. 感谢原出题人的贡献:第一题 CF1422C, ...
- 2015 HDU 计算机学院 院赛 1003 玩骰子
Problem Description Nias与Ains都特别喜欢玩骰子,而且都自以为比对方玩得更溜. 终于有一天,他们决定用骰子来一决高下! 一般的骰子玩法已经不足以体现他们的水平了,于是 ...
- pat 团体天梯赛 L2-011. 玩转二叉树
L2-011. 玩转二叉树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜 ...
- 繁华模拟赛 Evensgn玩序列
#include<iostream> #include<cstdio> #include<string> #include<cstring> #incl ...
- 20220303模拟赛题解and总结
目录 总结 A.不幸的7 B.选举 C. 差的绝对值之和 D. 路径通过 总结 初一第一 一般,最后一题没打好 不难发现,教练出水了,可能是信心赛 A.不幸的7 暴力,没有逻辑可言 #include& ...
- N(C)O(S)I(P)P 2019 退役记
N(C)O(S)I(P)P 2019 退役记 day-4 今天下午老师突然咕了,于是一下午欢乐时光 今天上午考试T3线段树维护个区间加,区间乘 一遍过编译,一遍过样例(第一次,俺比较弱(虽然也发现和暴 ...
- [日常] NOIP前集训日记
写点流水账放松身心... 10.8 前一天考完NHEEE的一调考试终于可以开始集训了Orz (然后上来考试就迟到5min, GG) T1维护队列瞎贪心, 过了大样例交上去一点也不稳...T出翔只拿了5 ...
- HEOI2017 游记
你若安好,便是晴天. …… 人就像命运下的蝼蚁,谁也无法操控自己的人生. ——阮行止 …… Day 0 中午就要出发了,上午教练还搞了一场欢乐信心赛,然而还是挂惨了.T3是bzoj的原题,但是当时写的 ...
随机推荐
- day7 opencv+python 读取视频,没有东西
1.读取视频man.avi, 报错. 我的视频和文件在同一目录下. #coding=utf-8 import numpy as np import cv2 cap = cv2.VideoCapture ...
- FFT&NTT总结
FFT&NTT总结 一些概念 \(DFT:\)离散傅里叶变换\(\rightarrow O(n^2)\)计算多项式卷积 \(FFT:\)快速傅里叶变换\(\rightarrow O(nlogn ...
- 3060 抓住那头奶牛 USACO
3060 抓住那头奶牛 USACO 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description 农夫约翰被告知一头逃跑奶牛的位置,想要立即抓住它, ...
- Scrapy爬取美女图片第四集 突破反爬虫(上)
本周又和大家见面了,首先说一下我最近正在做和将要做的一些事情.(我的新书<Python爬虫开发与项目实战>出版了,大家可以看一下样章) 技术方面的事情:本次端午假期没有休息,正在使用fl ...
- tomcat 设定自定义图片路径
1.问题 平常图片路径都是在项目目录下存放,都是ip地址+端口号+项目名+图片路径,因为项目需要要把图片从tomcat中分离出来,并且设置可以通过自定义地址访问自定义图片路径. 2.解决 在 tomc ...
- selenium webdriver API详解(二)
本系列主要讲解webdriver常用的API使用方法(注意:使用前请确认环境是否安装成功,浏览器驱动是否与谷歌浏览器版本对应) 一:获取当前页面的title(一般获取title用于断言) from s ...
- 人脸辨识,用树莓派Raspberry Pi实现舵机云台追踪脸孔
影像辨识作为近年最热门的专业技术之一,广泛用于智慧监视器.车电监控.智慧工厂.生物医疗电子等等:其中,人脸辨识是一个很重要的部分,网络上已经有相当多的资源可供下载使用:于是我们使用舵机云台作为镜头旋转 ...
- 美国末日AI System设计分享
引言 好久没有写博客了,这半年在游戏公司工作,过得比较充实,每天不是add feature就是debug,所以忽视了写博客.今天发一篇关于AI博客. 主要是最近看了一些关于"The Last ...
- C#判断字符串中是否有数字
// <summary> /// 提取字符串中的数字字符串 /// </summary> /// <param name="str"></ ...
- Haproxy + Rabbit 集群 简要介绍
# 两台主机都安装上rabbitMQ yum install -y rabbitmq-server # 两台主机都配置/etc/hosts文件 192.168.23.10 rabbitmq1 19 ...