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的更多相关文章

  1. 「THP3考前信心赛」解题报告

    目录 写在前面&总结: T1 T2 T3 T4 写在前面&总结: \(LuckyBlock\) 良心出题人!暴力分给了 \(120pts\) \(T1\) 貌似是个结论题,最后知道怎么 ...

  2. 「THP3考前信心赛」题解

    目录 写在前面 A 未来宇宙 B 空海澄澈 C 旧约酒馆 算法一 算法二 D 博物之志 算法一 算法二 算法三 写在前面 比赛地址:THP3 考前信心赛. 感谢原出题人的贡献:第一题 CF1422C, ...

  3. 2015 HDU 计算机学院 院赛 1003 玩骰子

    Problem Description   Nias与Ains都特别喜欢玩骰子,而且都自以为比对方玩得更溜.  终于有一天,他们决定用骰子来一决高下!  一般的骰子玩法已经不足以体现他们的水平了,于是 ...

  4. pat 团体天梯赛 L2-011. 玩转二叉树

    L2-011. 玩转二叉树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜 ...

  5. 繁华模拟赛 Evensgn玩序列

    #include<iostream> #include<cstdio> #include<string> #include<cstring> #incl ...

  6. 20220303模拟赛题解and总结

    目录 总结 A.不幸的7 B.选举 C. 差的绝对值之和 D. 路径通过 总结 初一第一 一般,最后一题没打好 不难发现,教练出水了,可能是信心赛 A.不幸的7 暴力,没有逻辑可言 #include& ...

  7. N(C)O(S)I(P)P 2019 退役记

    N(C)O(S)I(P)P 2019 退役记 day-4 今天下午老师突然咕了,于是一下午欢乐时光 今天上午考试T3线段树维护个区间加,区间乘 一遍过编译,一遍过样例(第一次,俺比较弱(虽然也发现和暴 ...

  8. [日常] NOIP前集训日记

    写点流水账放松身心... 10.8 前一天考完NHEEE的一调考试终于可以开始集训了Orz (然后上来考试就迟到5min, GG) T1维护队列瞎贪心, 过了大样例交上去一点也不稳...T出翔只拿了5 ...

  9. HEOI2017 游记

    你若安好,便是晴天. …… 人就像命运下的蝼蚁,谁也无法操控自己的人生. ——阮行止 …… Day 0 中午就要出发了,上午教练还搞了一场欢乐信心赛,然而还是挂惨了.T3是bzoj的原题,但是当时写的 ...

随机推荐

  1. Drupal7重置密码方法

    Drupal版本 7.40 方法1: 根目录index.php添加 require_once 'includes/password.inc'; require_once 'includes/boots ...

  2. Django——POST请求及Action触发事件

    添加网页login,将类型置为post,并添加action page,也就是之前写好的页面 添加page网页的views函数,要求获取post指令,如果username及password均正确则跳转到 ...

  3. 发送请求工具—Advanced REST Client的安装使用

    1. 0 下载得到Advanced-REST-client_v3.1.9.zip 链接:http://pan.baidu.com/s/1c0vUnJi 密码:z34d 1.1 解压Advanced-R ...

  4. CF刷题-Codeforces Round #481-D. Almost Arithmetic Progression

    题目链接:https://codeforces.com/contest/978/problem/D 题解: 题目的大意就是:这组序列能否组成等差数列?一旦构成等差数列,等差数列的公差必定确定,而且,对 ...

  5. Animator & Timeline

    using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Pla ...

  6. Angular7运行机制--根据腾讯课堂米斯特吴 《Angular4从入门到实战》学习笔记分析完成

  7. mysql中latin1编码中文转utf8

    在mysql中,对应的表字段编码通常默认为lartin1编码,在本地客户端显示的时候看着是乱码,但是通过mysql -u -p -h命令登录后,select查询到数据是正常的,通过jdbc或者php等 ...

  8. 7. I/O复用

    一.I/O复用的特点 能同时监听多个文件描述符 自身是阻塞的 当多个文件描述符同时就绪时,如果不采取额外的措施,程序就只能按顺序依次处理其中的每一个文件描述符 由于其第三个特点,所以服务器程序看起来仍 ...

  9. 效能检测 psp

    1.本周psp: 2.本周进度条: 3.累计进度图(折线图) 4.psp饼状图:

  10. vue+vue-video-player实现弹窗播放视频

    将视频播放器标签放在对话框标签中,实现弹窗 template 中 <el-dialog :visible.sync="dialogVisible" width='680px' ...