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的原题,但是当时写的 ...
随机推荐
- day1 HTML - <head>
1.html是什么? 超文本标记语言(Hypertext Markup Language,HTML) <!DOCTYPE html> <html lang="en" ...
- 【HNOI2014】世界树
题面 题解 虚树好题(只是细节太多) 构出虚树后,一定要仔细梳理关键点之间的点是上面属于父亲,下面属于儿子. 然后二分出所有的点的所属就可以了 代码 #include<cstdio> #i ...
- Django视图层详细介绍
1 视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. ...
- 11-Dockerfile构建镜像
用 Dockerfile 创建上节的 ubuntu-with-vi,其内容则为: FROM ubuntu RUN apt-get update && apt-get install v ...
- 简述AQS原理
这是一道面试题:简述AQS原理 AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态.如果被请求的共享资源被占用,那么就需要一套线程阻塞 ...
- [转]oracle数据库定时任务dbms_job的用法详解
这篇文章给大家详细介绍了dbms_job的用法,用于安排和管理作业队列,通过使用作业,可以使ORACLE数据库定期执行特定的任务.有需要的朋友们可以参考借鉴. 一.dbms_job涉及到的知识点 ...
- 九个很有用的php功能
1. 函数的任意数目的参数 你可能知道PHP允许你定义一个默认参数的函数.但你可能并不知道PHP还允许你定义一个完全任意的参数的函数 下面是一个示例向你展示了默认参数的函数: 1 2 3 4 5 6 ...
- Python中的构造函数
Python中的构造函数是__init__函数.在Python中,子类如果定义了构造函数,而没有调用父类的,那么Python不会自动调用,也就是说父类的构造函数不会执行. 比如有test.py的mod ...
- 【Alpha】阶段第一次Scrum Meeting
[Alpha]阶段第一次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 后端接口开发 测试接口,修正bug 赵智源 撰写测试方案书 部署实际任务和编写测试样例 ...
- 20172321 2018-2019《Java软件结构与数据结构》第三周学习总结
教材学习内容总结 第五章 5.1概述 队列是一种线性集合,其元素从一端加入,从另一端删除:队列的处理方式是先进先出(First in First out). 与栈的比较(LIFO) 栈是一端操作,先进 ...