题目描述
树链是指树里的一条路径。美团外卖的形象代言人袋鼠先生最近在研究一个特殊的最长树链问题。现在树中的每个点都有一个正整数值,他想在树中找出最长的树链,使得这条树链上所有对应点的值的最大公约数大于1。请求出这条树链的长度。

输入描述:
第1行:整数n(1 ≤ n ≤ 100000),表示点的个数。
第2~n行:每行两个整数x,y表示xy之间有边,数据保证给出的是一棵树。
第n+1行:n个整数,依次表示点1~n对应的权值(1 ≤ 权值 ≤ 1,000,000,000)。

输出描述:
满足最长路径的长度

输入例子:
4
1 2
1 3
2 4
6 4 5 2

输出例子:
3

题解:也许当时我并没有报名参加比赛是个错误的决定?

看起来10^9很虚,但是我们分解质因数只需要预处理出3*10^4里的质数,实际上只有3000多个,3000*n完全不虚,所以我们可以先将n个数全都分解质因数。

然后我们枚举每个质数,枚举所有包含这些质数的点,看一下这些点在树上能形成的最长的链有多长。具体做法是我们将这些点按照深度从大到小排序,然后更新每个点父亲的子树中到父亲的最长链、次长链分别是多长,乱搞一下就行了。

T4帮同学1A了,但是一到1000分的题才拿了700多分,其他题看都没看,我只能默默在这边打辅助了~

如果你把这个代码交上去你就废了呵呵呵~

#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=100010;
int to[maxn<<1],nxt[maxn<<1],head[maxn],v[maxn],d1[maxn],d2[maxn],p[103600],fa[maxn],dep[maxn],pri[3600];
bool np[33000];
vector<int> s[103600];
map<int,int> mp;
int rd()
{
int ret=0; char gc=getchar();
while(gc<'0'||gc>'9') gc=getchar();
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret;
}
void dfs(int x)
{
for(int i=head[x];i!=-1;i=nxt[i]) if(to[i]!=fa[x]) fa[to[i]]=x,dep[to[i]]=dep[x]+1,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()
{
n=rd();
int i,j,a,b;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
for(i=1;i<=n;i++) v[i]=rd(),m=max(m,v[i]);
m=ceil(sqrt(1.0*m));
for(i=2;i<=m;i++)
{
if(!np[i]) pri[++tot]=i,mp[i]=tot;
for(j=1;j<=tot&&i*pri[j]<=m;j++)
{
np[i*pri[j]]=1;
if(i%pri[j]==0) break;
}
}
dep[1]=1,dfs(1),mor=tot;
for(i=1;i<=n;i++)
{
for(j=1;j<=tot&&pri[j]*pri[j]<=v[i];j++)
{
if(v[i]%pri[j]==0)
{
s[j].push_back(i);
while(v[i]%pri[j]==0) v[i]/=pri[j];
}
}
if(v[i]>1)
{
if(mp.find(v[i])==mp.end()) mp[v[i]]=++mor;
s[mp[v[i]]].push_back(i);
}
}
ans=1;
for(i=1;i<=mor;i++) p[i]=i;
sort(p+1,p+mor+1,cmp1);
for(i=1;i<=mor;i++)
{
b=p[i];
if(s[b].size()<=ans) break;
sort(s[b].begin(),s[b].end(),cmp2);
for(j=0;j<s[b].size();j++) a=s[b][j],d1[a]++,d2[a]++,ans=max(ans,d1[a]+d2[a]-1),updata(fa[a],a);
for(j=0;j<s[b].size();j++) a=s[b][j],d1[a]=d2[a]=d1[fa[a]]=d2[fa[a]]=0;
}
printf("%d",ans);
return 0;
}

【CodeM初赛A轮】D 分解质因数+暴力的更多相关文章

  1. 【CodeM初赛B轮】F 期望DP

    [CodeM初赛B轮]F 题目大意:有n个景点,m条无向边,经过每条边的时间需要的时间是li,在第i个景点游览花费的时间是ti,游览完第i个景点可以获得的满意度是hi.你的总时间为k,起初你等概率的选 ...

  2. 【CodeM初赛B轮】A 贪心

    [CodeM初赛B轮]A 题目大意:给你一棵树,起初所有点都是白色的,你每次都能选择一个白点i,将这个点i到根路径上的所有到i的距离<k[i]的点都染成黑色(根和i也算,已经被染成黑色的点还是黑 ...

  3. CodeM初赛B轮

    做什么啊,我这么菜,应该弃赛的 [编程|1500分] 子串 时间限制:3秒空间限制:32768K 题目描述 给出一个正整数n,我们把1..n在k进制下的表示连起来记为s(n,k),例如s(16,16) ...

  4. 美团CodeM初赛B轮 合并字符串的价值 (线段树,分类讨论)

    输入两个字符串a和b,合并成一个串c,属于a或b的字符在c中顺序保持不变.如"ACG"和"UT"可以被组合成"AUCTG"或"AC ...

  5. 美团2018年CodeM大赛-初赛B轮 B 配送(最短路)

    美团2018年CodeM大赛-初赛B轮 B 配送 题意 题解 对于每个任务,只要从上个任务的终点出发即可. 时间.地点很少,可以算出每个地点-时间的最小花费. 以题目描述的起点终点起始结束时间建图,很 ...

  6. Java实现 蓝桥杯 算法提高 分解质因数(暴力)

    试题 算法提高 分解质因数 问题描述 给定一个正整数n,尝试对其分解质因数 输入格式 仅一行,一个正整数,表示待分解的质因数 输出格式 仅一行,从小到大依次输出其质因数,相邻的数用空格隔开 样例输入 ...

  7. cdoj 1246 每周一题 拆拆拆~ 分解质因数

    拆拆拆~ Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1246 Descri ...

  8. #6164. 「美团 CodeM 初赛 Round A」数列互质-莫队

    #6164. 「美团 CodeM 初赛 Round A」数列互质 思路 : 对这个题来言,莫队可以 n*根号n 离线处理出各个数出现个的次数 ,同时可以得到每个次数出现的次数 , 但是还要处理有多少 ...

  9. POJ 1142:Smith Numbers(分解质因数)

                                   Smith Numbers Time Limit: 1000MS   Memory Limit: 10000K Total Submiss ...

随机推荐

  1. perl一次读取多行文本的策略

    在处理文本时,经常遇到这种情况:就是我们须要把两行文本做一个比較,然后选择性输出. 而在while(<FILEHAND>){do something}程序块中默认仅仅能一次读取一行.笔者在 ...

  2. ES6里关于数字的拓展

    一.指数运算符 ES6引入的唯一一个JS语法变化是求幂运算符,它是一种将指数应用于基数的数学运算.JS已有的Math.pow()方法可以执行求幂运算,但它也是为数不多的需要通过方法而不是正式的运算符来 ...

  3. bitcoin-qt忘记密码

    客户端有钱包加密功能,输入密码可以增强安全性. 但是,如果你把钱包文件弄丢了,那即使设了密码,币也会丢. 关闭bitcoin-qt,把钱包文件wallet.dat 剪到其他地方(但不要删除),然后重新 ...

  4. 转: Servlet 工作原理解析 from ibm

    评点: 比较深入的讲了servlet容器, 作者许令波 (这个文章好像来自他自己的书中java web...) https://www.ibm.com/developerworks/cn/java/j ...

  5. 倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 88怎么办

    请确认在TWINCAT在线模式下,把Drive的Modes of operation改为8       更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku.com ...

  6. Java 调用存储过程、函数

     一.Java调用存储Oracle存储过程 测试用表: --创建用户表 create table USERINFO ( username ) not null, password ) not null ...

  7. Python_Select解析

    selcet(等待I/O完成)的介绍: select同时监控多个socket,select()的机制提供了fd_set的数据结构,实际是long类型的数组,优点是跨平台性,select的缺点在于单个进 ...

  8. PLSQL Developer设置技巧

    1.右键菜单 在PL/SQL Developer(下面简称PLD)中的每一个文本编辑窗口,如SQL Window,Command Window和Porgram Window,右键点击某个对象名称,会弹 ...

  9. JDBC技术总结(二)

    上一节主要讲了JDBC的基本操作,这一节主要总结一下JDBC如何处理大文本.如何处理图片以及进行批处理. 1.JDBC处理大文本 在MySQL中,大文本是text类型,使用Java操作数据库中的大文本 ...

  10. Android源码在线查看网址

    1 http://www.grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/