题意:给出一棵点带权的树,求i$\in$[1,200000]所有路径的上点权的gcd==i的个数。

考虑点分治,对于一棵以u为根的子树,如何统计经过u的路径的答案?

显然既然是经过点u的路径,那么所有经过u的路径上的点权的gcd肯定是点u的点权的约数。

暴力算下,2e5以内最多只有160个约数。

然后dfs出u子树里所有点到u路径的gcd,然后用个桶,最多\(u的点权的约数个数^2\)数下数就行了,但是实际应该是远远不满的。

最慢的一个点1404ms,4.5s的时限应该没什么问题。

然而这题的标签里有个dp(滑稽

//by zykykyk
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
#define ll long long
#define For(i,x,y) for (register int i=(x);i<=(y);i++)
#define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
#define cross(i,k) for (register int i=first[k];i;i=last[i])
inline ll read(){
ll x=0;int ch=getchar(),f=1;
while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
if (ch=='-'){f=-1;ch=getchar();}
while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int N = 2e5+10;
int n,x,y,Size,rt,a[N];
ll ans[N];
int tot,first[N],last[N<<1],to[N<<1];
inline void Add(int x,int y){to[++tot]=y,last[tot]=first[x],first[x]=tot;}
int size[N],Max[N];
bool vis[N];
inline void GetRoot(int u,int fa){
Max[u]=0,size[u]=1;
cross(i,u) if (to[i]!=fa&&!vis[to[i]]) GetRoot(to[i],u),size[u]+=size[to[i]],Max[u]=max(Max[u],size[to[i]]);
Max[u]=max(Max[u],Size-size[u]);
if (Max[rt]>Max[u]) rt=u;
}
int cnt,g[N];
ll b[N];
inline int gcd(int a,int b){return !b?a:gcd(b,a%b);}
inline void dfs(int u,int fa,int Gcd,int x,int rt){
if (x!=1||x==1&&u!=rt) g[++cnt]=Gcd,b[Gcd]++;
cross(i,u) if (to[i]!=fa&&!vis[to[i]]) dfs(to[i],u,gcd(Gcd,a[to[i]]),x,rt);
}
inline void solve(int u){
cnt=0,dfs(u,u,a[u],1,u),vis[u]=1;
sort(g+1,g+1+cnt);
int tot=unique(g+1,g+1+cnt)-g-1;
For(i,1,tot){
ans[g[i]]+=b[g[i]]+b[g[i]]*(b[g[i]]-1)/2;
For(j,i+1,tot) ans[gcd(g[i],g[j])]+=b[g[i]]*b[g[j]];
}
For(i,1,tot) b[g[i]]=0;
cross(k,u)
if (!vis[to[k]]){
cnt=0,dfs(to[k],u,gcd(a[u],a[to[k]]),0,to[k]);
sort(g+1,g+1+cnt);
int tot=unique(g+1,g+1+cnt)-g-1;
For(i,1,tot){
ans[g[i]]-=b[g[i]]*(b[g[i]]-1)/2;
For(j,i+1,tot) ans[gcd(g[i],g[j])]-=b[g[i]]*b[g[j]];
}
For(i,1,tot) b[g[i]]=0;
}
cross(i,u) if (!vis[to[i]]) Size=size[to[i]],rt=0,GetRoot(to[i],u),solve(rt);
}
int main(){
n=read();
For(i,1,n) a[i]=read(),ans[a[i]]++;
For(i,1,n-1) x=read(),y=read(),Add(x,y),Add(y,x);
Size=n,Max[0]=1e9,GetRoot(1,1),solve(rt);
For(i,1,N-10) if (ans[i]) printf("%d %lld\n",i,ans[i]);
}

Codeforces 990G 点分治+暴力的更多相关文章

  1. CodeForces - 990G (点分治+链表计数)

    题目:https://vjudge.net/contest/307753#problem/J 题意:一棵树,每个点都有个权值,现在问你,树上gcd每个不同的数有多少个 思路:点分治,首先范围只有 1e ...

  2. Codeforces Round #355 (Div. 2) D. Vanya and Treasure 分治暴力

    D. Vanya and Treasure 题目连接: http://www.codeforces.com/contest/677/problem/D Description Vanya is in ...

  3. codeforces 724B Batch Sort(暴力-列交换一次每行交换一次)

    题目链接:http://codeforces.com/problemset/problem/724/B 题目大意: 给出N*M矩阵,对于该矩阵有两种操作: (保证,每行输入的数是 1-m 之间的数且不 ...

  4. codeforces 897A Scarborough Fair 暴力签到

    codeforces 897A Scarborough Fair 题目链接: http://codeforces.com/problemset/problem/897/A 思路: 暴力大法好 代码: ...

  5. 【BZOJ 4059】 (分治暴力|扫描线+线段树)

    4059: [Cerc2012]Non-boring sequences Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 632  Solved: 22 ...

  6. Codeforces A. Playlist(暴力剪枝)

    题目描述: Playlist time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  7. Codeforces 1101D 点分治

    题意:有一颗树,每个点有一个点权,边权都是1,问路径上的所有点的gcd不是1的最长路径是多少? 思路:之前补这道题的时候,用分解质因数 + 树形DP做的,其实用点分治可以更暴力一点.对于这类统计树上路 ...

  8. Codeforces 293E 点分治+cdq

    Codeforces 293E 传送门:https://codeforces.com/contest/293/problem/E 题意: 给你一颗边权一开始为0的树,然后给你n-1次操作,每次给边加上 ...

  9. codeforces 161D 点分治

    传送门:https://codeforces.com/problemset/problem/161/D 题意: 求树上点对距离恰好为k的点对个数 题解: 与poj1741相似 把点分治的模板改一下即可 ...

随机推荐

  1. phpStudy 虚拟主机

    转载:http://blog.csdn.net/sinat_35861664/article/details/53557574 windows下配置虚拟主机,实现多域名访问本地项目目录 1.Apach ...

  2. 面试整理(3)js事件委托

    事件委托主要用于一个父容器下面有很多功能相仿的子容器,这时候就需要将子容器的事件监听交给父容器来做.父容器之所以能够帮子容器监听其原理是事件冒泡,对于子容器的点击在冒泡时会被父容器捕获到,然后用e.t ...

  3. 【leetcode 简单】第三十六题 最小栈

    设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈. push(x) -- 将元素 x 推入栈中. pop() -- 删除栈顶的元素. top() -- 获取栈顶元素. ...

  4. 【leetcode 简单】第十九题 删除排序链表中的重复元素

    给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: 1->1->2->3-&g ...

  5. arch点击硬盘无法挂载

    出现问题如下 在使用xfce4桌面的时候在点击硬盘图标时可以挂载虽然要求你输入root密码 但是在使用openbox的时候点击硬盘图标却出现如下提示,权限的问题 Not authorized to p ...

  6. webconfig的配置解析

    <?xml version="1.0"?> <!--注意: 除了手动编辑此文件以外,您还可以使用 Web 管理工具来配置应用程序的设置.可以使用 Visual S ...

  7. 微信小程序开发定制

    上海软件定制专家:http://www.dzonly.com/?from=timeline

  8. The algorithm of entropy realization

    近似熵的一种快速实用算法 Pincus提出的近似熵算法中有很多冗余的计算,效率低,速度慢,不利于实际应用,洪波等人在定义的基础上引入二值距离矩阵的概率,提出了一种实用快速的算法. function A ...

  9. html的loadrunner脚本2

    Action(){ char buf[1911]; //¶¨Òå×Ö·ûÊý×飬Ö÷ÒªÓÃÓÚдÈëXML±¨Îĵ½»º³åÇø char str_Body[4086]; //³Ð½Ó±¨Î ...

  10. python安装模块的时候报错error: command 'gcc' failed with exit status 1

    [情况] 在写Python代码的时候,需要用到psutil模块,需要安装. 但是在安装时,报错:error: command 'gcc' failed with exit status 1 [解决步骤 ...