Codeforces 1101D 点分治
题意:有一颗树,每个点有一个点权,边权都是1,问路径上的所有点的gcd不是1的最长路径是多少?
思路:之前补这道题的时候,用分解质因数 + 树形DP做的,其实用点分治可以更暴力一点。对于这类统计树上路径的问题,点分治是一种通用,高效的解法。对于所有的路径,无非两种情况:经过某个点,不经过某个点,我们对于每个点统计的相当于是经过该点的路径的信息。点分治为以下几步:1:找重心。2:以找到的重心为根,解决经过该点的路径的问题。3:递归的找其它子树的重心,解决问题。找经过该点的路径时,直接搜索求gcd,所有说非常暴力无脑。找到之后暴力合并。复杂度应该是O(n * (log(n) ^ 2));
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200010;
vector<int> G[maxn];
map<int, int> mp, tmp;
map<int, int>::iterator it1, it2;
bool v[maxn];
int sz[maxn], tot, mx, root, a[maxn], ans;
void add(int x, int y) {
G[x].push_back(y);
G[y].push_back(x);
}
void get_root(int x, int fa) {
sz[x] = 1;
int max_part = 0;
for (auto y : G[x]) {
if(y == fa || v[y]) continue;
get_root(y, x);
sz[x] += sz[y];
max_part = max(max_part, sz[y]);
}
max_part = max(max_part, tot - sz[x]);
if(max_part < mx) {
mx = max_part;
root = x;
}
}
void get_ans(int x, int dep, int fa, int z) {
if(z == 1) return;
tmp[z] = max(tmp[z], dep);
for (auto y : G[x]) {
if(v[y] || y == fa) continue;
get_ans(y, dep + 1, x, __gcd(z, a[y]));
}
}
void solve(int x) {
mp.clear();
mp[a[x]] = 1;
for (auto y : G[x]) {
if(v[y]) continue;
tmp.clear();
get_ans(y, 1, x, __gcd(a[x], a[y]));
for (it1 = mp.begin(); it1 != mp.end(); it1++) {
for (it2 = tmp.begin(); it2 != tmp.end(); it2++) {
if(__gcd(it1 -> first, it2 -> first) != 1) {
ans = max(ans, (it1 -> second) + (it2 -> second));
}
}
}
for (it2 = tmp.begin(); it2 != tmp.end(); it2++) {
mp[it2 -> first] = max(mp[it2 -> first], (it2 -> second) + 1);
}
}
}
void div(int x) {
v[x] = 1;
solve(x);
for (auto y : G[x]) {
if(v[y]) continue;
tot = sz[y];
mx = 1e6;
get_root(y, x);
div(root);
}
}
int main() {
int n, x, y;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if(a[i] > 1) ans = 1;
}
for (int i = 1; i < n; i++) {
scanf("%d%d", &x, &y);
add(x, y);
}
tot = n;
mx = 1e6;
get_root(1, -1);
div(root);
printf("%d\n", ans);
}
Codeforces 1101D 点分治的更多相关文章
- CodeForces - 1101D:GCD Counting (树分治)
You are given a tree consisting of n vertices. A number is written on each vertex; the number on ver ...
- Codeforces 293E 点分治+cdq
Codeforces 293E 传送门:https://codeforces.com/contest/293/problem/E 题意: 给你一颗边权一开始为0的树,然后给你n-1次操作,每次给边加上 ...
- codeforces 161D 点分治
传送门:https://codeforces.com/problemset/problem/161/D 题意: 求树上点对距离恰好为k的点对个数 题解: 与poj1741相似 把点分治的模板改一下即可 ...
- Codeforces 475D CGCDSSQ(分治)
题意:给你一个序列a[i],对于每个询问xi,求出有多少个(l,r)对使得gcd(al,al+1...ar)=xi. 表面上是询问,其实只要处理出每个可能的gcd有多少个就好了,当左端点固定的时候,随 ...
- Codeforces 888G(分治+trie)
按位贪心,以当前考虑位是0还是1将数分成两部分,则MST中这两部分之间只会存在一条边,因为一旦有两条或以上的边,考虑两条边在原图中所成的环,显然这两条边有一条是环上的权值最大边,不会出现在MST中.则 ...
- Codeforces 888G Xor-MST - 分治 - 贪心 - Trie
题目传送门 这是一条通往vjudge的高速公路 这是一条通往Codeforces的高速公路 题目大意 给定一个$n$阶完全图,每个点有一个权值$a_{i}$,边$(i, j)$的权值是$(a_{i}\ ...
- Codeforces 990G 点分治+暴力
题意:给出一棵点带权的树,求i\(\in\)[1,200000]所有路径的上点权的gcd==i的个数. 考虑点分治,对于一棵以u为根的子树,如何统计经过u的路径的答案? 显然既然是经过点u的路径,那么 ...
- 【题解】Radio stations Codeforces 762E CDQ分治
虽然说好像这题有其他做法,但是在问题转化之后,使用CDQ分治是显而易见的 并且如果CDQ打的熟练的话,码量也不算大,打的也很快,思维难度也很小 没学过CDQ分治的话,可以去看看我的另一篇博客,是CDQ ...
- Radio stations CodeForces - 762E (cdq分治)
大意: 给定$n$个三元组$(x,r,f)$, 求所有对$(i,j)$, 满足$i<j, |f_i-f_j|\le k, min(r_i,r_j)\ge |x_i-x_j|$ 按$r$降序排, ...
随机推荐
- springboot打包成jar文件无法正常运行,解决办法已经找到
1.用intellij idea 创建了一个springboot的项目,前期都运行的好好的,在ide中可以正常运行,但是打包成Jar运行却一直报错. 2.经过不懈探索,终于找到解决办法 3.首先,找到 ...
- java定义类
package java04; /* * 定义一个类,用来模拟“学生”,其中包含量两个组合部分 * * 格式: * public class ClassName{ * //成员变量 * //成员方法 ...
- 非阻塞套接字与IO多路复用(转,python实现版)
非阻塞:指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回.epoll工作在非阻塞模式时,才会发挥作用. 我们了解了socket之后已经知道,普通套接字实现的服务端的缺陷:一次只能服务一个 ...
- Python的"random"函数的使用(一)
random.randrange(1,10) 随机产生0~7之间的整数,不包含7. random.sample(range(100), 5) 随机从range(100)中产生5个数,放入一个list. ...
- linux网络接口,struct ifreq struct ifconf结构
网络相关的ioctl请求的request参数及arg地址必须指向的数据类型如下表所示: 接口 SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFBRDADDR SI ...
- Oracle数据库之触发器(二)
DML触发器是指在进行insert.update或delete操作时触发的程序体.如果你想在用户对数据进行操作时,记录或限制其操作,就可以用DML触发器.举例来说,我想统计我的网站用户的注册.注销或者 ...
- [CSP-S模拟测试]:marshland(最大费用可行流)
题目描述 前方有一片沼泽地.方便地,我们用一个$n\times n$的网格图来描述它,每一个格子代表着沼泽地的一小片区域.其中$(1,1)$代表网格图的左上角,$(n,n)$代表网格图的右下角.若用$ ...
- 【Java架构:持续交付】一篇文章搞掂:Jenkins
一.安装 1.使用yum本地安装 1.1.使用yum安装JDK a.检查系统是否有安装open-jdk rpm -qa |grep java rpm -qa |grep jdk rpm -qa |gr ...
- 日期和时间格式(ISO 8601)
参考 ISO 8601 - Wikipedia ISO 8601 Date and time format
- QTP使用dictionary 对象
1. 创建即使用Dictionary对象 ' 创建Dictionary对象Set Dic = CreateObject("Scripting.Dictionary")' 添加Dic ...