HDU 4812 D Tree
思路:
点分治
先预处理好1e6 + 3以内到逆元
然后用map 映射以分治点为起点的链的值a 成他的下标 u
然后暴力跑出以分治点儿子为起点的链的值b,然后在map里查找inv[b]*k
代码:
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head const int MOD = 1e6 + ;
const int INF = 0x7f7f7f7f;
const int N = 1e5 + ;
int inv[MOD + ], mp[MOD + ], head[N], mxsz[N], sz[N], v[N], cnt = , rt = , n, k, ans1, ans2;
int deep[N], dis[N], id[N], top = ;
bool vis[N];
struct edge {
int to, nxt;
}edge[N*];
void add_edge(int u, int v) {
edge[cnt].to = v;
edge[cnt].nxt = head[u];
head[u] = cnt++;
}
void init() {
inv[] = ;
for (int i = ; i < MOD; i++) inv[i] = (MOD - MOD/i) * 1LL * inv[MOD%i] % MOD;
}
void update(int x, int y) {
int t = (1LL * inv[x] * k) % MOD;
int now = mp[t];
if(!now) return ;
if(now > y) swap(now, y);
if(now < ans1 || now == ans1 && y < ans2) ans1 = now, ans2 = y;
}
void get_rt(int o, int u) {
sz[u] = , mxsz[u] = ;
for (int i = head[u]; ~i; i = edge[i].nxt) {
if(edge[i].to != o && !vis[edge[i].to]) {
get_rt(u, edge[i].to);
sz[u] += sz[edge[i].to];
mxsz[u] = max(mxsz[u], sz[edge[i].to]);
}
}
mxsz[u] = max(mxsz[u], n - sz[u]);
if(mxsz[u] < mxsz[rt]) rt = u;
}
void get_d(int o, int u) {
deep[++top] = dis[u];
id[top] = u;
for (int i = head[u]; ~i; i = edge[i].nxt) {
if(!vis[edge[i].to] && edge[i].to != o) {
dis[edge[i].to] = (1LL * dis[u] * v[edge[i].to])%MOD;
get_d(u, edge[i].to);
}
}
}
void solve(int u) {
vis[u] = true;
mp[v[u]] = u;
for (int i = head[u]; ~i; i = edge[i].nxt) {
if(!vis[edge[i].to]) {
top = , dis[edge[i].to] = v[edge[i].to];
get_d(u, edge[i].to);
for (int j = ; j <= top; j++) update(deep[j], id[j]);
top = , dis[edge[i].to] = (1LL * v[u] * v[edge[i].to])%MOD;
get_d(u, edge[i].to);
for (int j = ; j <= top; j++) {
int t = deep[j];
if(!mp[t] || id[j] < mp[t]) mp[t] = id[j];
}
}
}
mp[v[u]] = ;
for (int i = head[u]; ~i; i = edge[i].nxt) {
if(!vis[edge[i].to]) {
top = , dis[edge[i].to] = (1LL * v[u] * v[edge[i].to])%MOD;
get_d(u, edge[i].to);
for (int j = ; j <= top; j++) mp[deep[j]] = ;
}
}
for (int i = head[u]; ~i; i = edge[i].nxt) {
if(!vis[edge[i].to]) {
mxsz[] = n = sz[edge[i].to];
get_rt(rt = , edge[i].to);
solve(rt);
}
}
}
int main() {
init();
int u, V;
while(~scanf("%d%d", &n, &k)) {
mem(head, -);
mem(vis, false);
mem(mp, );
cnt = ;
ans1 = ans2 = INF;
for (int i = ; i <= n; i++) scanf("%d", &v[i]);
for (int i = ; i < n; i++) scanf("%d%d", &u, &V), add_edge(u, V), add_edge(V, u);
mxsz[] = n;
get_rt(rt = , );
solve(rt);
if(ans1 == INF) printf("No solution\n");
else printf("%d %d\n", ans1, ans2);
}
return ;
}
HDU 4812 D Tree的更多相关文章
- HDU - 4812 D Tree 点分治
http://acm.hdu.edu.cn/showproblem.php?pid=4812 题意:有一棵树,每个点有一个权值要求找最小的一对点,路径上的乘积mod1e6+3为k 题解:点分治,挨个把 ...
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- hdu 4812 D Tree(树的点分治)
D Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Total ...
- HDU 4812 D Tree 树分区+逆+hash新位置
意甲冠军: 特定n点树 K 以下n号码是正确的点 以下n-1行给出了树的侧. 问: 所以,如果有在正确的道路点图的路径 % mod = K 如果输出路径的两端存在. 多条路径则输出字典序最小的一条. ...
- HDU 4812 D Tree 树分治
题意: 给出一棵树,每个节点上有个权值.要找到一对字典序最小的点对\((u, v)(u < v)\),使得路径\(u \to v\)上所有节点权值的乘积模\(10^6 + 3\)的值为\(k\) ...
- HDU 4871 Shortest-path tree 最短路 + 树分治
题意: 输入一个带权的无向连通图 定义以顶点\(u\)为根的最短路生成树为: 树上任何点\(v\)到\(u\)的距离都是原图最短的,如果有多条最短路,取字典序最小的那条. 然后询问生成树上恰好包含\( ...
- hdu 4812 DTree (点分治)
D Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total S ...
- HDU 5513 Efficient Tree
HDU 5513 Efficient Tree 题意 给一个\(N \times M(N \le 800, M \le 7)\)矩形. 已知每个点\((i-1, j)\)和\((i,j-1)\)连边的 ...
- HDU 4925 Apple Tree(推理)
HDU 4925 Apple Tree 题目链接 题意:给一个m*n矩阵种树,每一个位置能够选择种树或者施肥,假设种上去的位置就不能施肥,假设施肥则能让周围果树产量乘2.问最大收益 思路:推理得到肯定 ...
随机推荐
- 一种基于 Numpy 的 TF-IDF 实现报告
一种基于 Numpy 的 TF-IDF 实现报告 摘要 本文使用了一种 state-of-the-art 的矩阵表示方法来计算每个词在每篇文章上的 TF-IDF 权重(特征).本文还将介绍基于 TF- ...
- SQLServer和MySql的区别总结
SqlServer支持like '%'+'87'+'%' 拼接字符串 但MySql里不支持,只能用CONCAT('%','87','%')拼接,否则异常 1.递归函数的区别类别表CREATE TAB ...
- bzoj 1614 Telephone Lines架设电话线 - 二分答案 - 最短路
Description Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务.于是,FJ必须为此向电信公司支付一定的费用. FJ的农场周围分布着N(1 <= N ...
- grep 正则匹配
\{0,n\}:至多n次 \{\ 匹配/etc/passwd文件中数字出现只是数字1次到3次 匹配/etc/grub2.cfg文件以一个空格开头匹配一个字符的文件的所有行 显示以LISTEN结尾的行 ...
- centos7.2 python2.7升级python3.6退格键不能用
yum install readline-devel ./configure --prefix=/usr/py/py3.6 (目录是自定义的这个根据实际情况来) make && ...
- utf-8并不"兼容" gb2312, gb18030
注意 utf-8 并不是 向下 兼容"gb2312 gb18030"等编码, 也并不是说, utf-8就是比 gb2312等高级的编码! 比如在terminal中, 你开始使用的 ...
- 在fedora23中安装virtualbox, 然后实现虚拟机irtualbox 或者 vmware 下的xp操作系统
参考: http://blog.csdn.net/statdm/article/details/7756788 参考: http://www.cnblogs.com/fengbohello/p/488 ...
- P4782 【模板】2-SAT 问题
https://www.luogu.org/problemnew/show/P4782 链接 https://www.luogu.org/problemnew/show/P4782 思路 选a就必须选 ...
- 【Dalston】【第三章】声明式服务调用(Feign)
当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,并且显得好傻.那 ...
- Spring Boot 2 入门
Spring Boot其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置. 参考网上资料,一路踩了几个坑,终于搞出了 ...