HDU 4812

思路:

点分治

先预处理好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的更多相关文章

  1. HDU - 4812 D Tree 点分治

    http://acm.hdu.edu.cn/showproblem.php?pid=4812 题意:有一棵树,每个点有一个权值要求找最小的一对点,路径上的乘积mod1e6+3为k 题解:点分治,挨个把 ...

  2. HDU 4812 D Tree 树分治+逆元处理

    D Tree Problem Description   There is a skyscraping tree standing on the playground of Nanjing Unive ...

  3. hdu 4812 D Tree(树的点分治)

    D Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total ...

  4. HDU 4812 D Tree 树分区+逆+hash新位置

    意甲冠军: 特定n点树 K 以下n号码是正确的点 以下n-1行给出了树的侧. 问: 所以,如果有在正确的道路点图的路径 % mod  = K 如果输出路径的两端存在. 多条路径则输出字典序最小的一条. ...

  5. HDU 4812 D Tree 树分治

    题意: 给出一棵树,每个节点上有个权值.要找到一对字典序最小的点对\((u, v)(u < v)\),使得路径\(u \to v\)上所有节点权值的乘积模\(10^6 + 3\)的值为\(k\) ...

  6. HDU 4871 Shortest-path tree 最短路 + 树分治

    题意: 输入一个带权的无向连通图 定义以顶点\(u\)为根的最短路生成树为: 树上任何点\(v\)到\(u\)的距离都是原图最短的,如果有多条最短路,取字典序最小的那条. 然后询问生成树上恰好包含\( ...

  7. hdu 4812 DTree (点分治)

    D Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)Total S ...

  8. HDU 5513 Efficient Tree

    HDU 5513 Efficient Tree 题意 给一个\(N \times M(N \le 800, M \le 7)\)矩形. 已知每个点\((i-1, j)\)和\((i,j-1)\)连边的 ...

  9. HDU 4925 Apple Tree(推理)

    HDU 4925 Apple Tree 题目链接 题意:给一个m*n矩阵种树,每一个位置能够选择种树或者施肥,假设种上去的位置就不能施肥,假设施肥则能让周围果树产量乘2.问最大收益 思路:推理得到肯定 ...

随机推荐

  1. Python3 Pandas的DataFrame格式数据写入excle文件、json、html、剪贴板、数据库

    Python3 Pandas的DataFrame格式数据写入excle文件.json.html.剪贴板.数据库 一.DataFrame格式数据 Pandas是Python下一个开源数据分析的库,它提供 ...

  2. 写给大忙人的nginx核心配置详解

    由于当前很多应该都是前后端分离了,同时大量的基于http的分布式和微服务架构,使得很多时候应用和不同项目组之间的系统相互来回调用,关系复杂.如果使用传统的做法,都在应用中进行各种处理和判断,不仅维护复 ...

  3. com.mchange.v2.c3p0.impl.NewPooledConnection@be1839d closed by a client的正确解答

    关于c3p0在debug模式下控制台抛出的如下异常: java.lang.Exception: DEBUG -- CLOSE BY CLIENT STACK TRACE at com.mchange. ...

  4. Codeforces Round 500 (Div 2) Solution

    从这里开始 题目地址 瞎扯 Problem A Piles With Stones Problem B And Problem C Photo of The Sky Problem D Chemica ...

  5. 2018年11月20日 远交近攻 list1

    list 列表用法 li=[1,2,3,"abc"] #列表中的元素,可以为数字或者字符串或者布尔值或者就是列表等,所有都能放进去 #列表中也能嵌套列表 pi=[1,2,3,[2, ...

  6. Docker 安装Hadoop HDFS命令行操作

    网上拉取Docker模板,使用singlarities/hadoop镜像 [root@localhost /]# docker pull singularities/hadoop 查看: [root@ ...

  7. Dubbo集群配置和官方文档

    集群配置: https://blog.csdn.net/zh520qx/article/details/63679908 https://www.cnblogs.com/hd3013779515/p/ ...

  8. Python入门 值内存管理与所有的关键字

    值内存管理 Python采用的是基于值得内存管理方式,如果为不同变量赋值为相同值,这个值在内存中只有一份,多个变量指向同一块内存地址. id(x) : 用于返回变量所指值的内存地址 x = 3 pri ...

  9. JavaI/O(输入/输出)

    File类 通过File类可以在程序中操作文件和目录,File能新建.删除.重命名文件和目录,但是不能访问文件内容本身. 理解I/O流 流(stream)是从起源(source)到接收(sink)的有 ...

  10. LOJ121 「离线可过」动态图连通性

    思路 动态图连通性的板子,可惜我不会在线算法 离线可以使用线段树分治,每个边按照存在的时间插入线段树的对应节点中,最后再dfs一下求出解即可,注意并查集按秩合并可以支持撤销操作 由于大量使用STL跑的 ...