hdu4812-D Tree (树的点分治)
昨天学了下树分治,今天补这道题,还是太不熟练了,写完之后一直超时。后来查出好多错= =比如v,u写倒了,比如+写成了取最值,比如。。。。爆int。。。查了两个多小时的错。。哭。。。(没想到进首页了
http://hzwer.com/6107.html 大神博客,代码清晰,照着这个改的
逆元预处理之前是没有见过的,学习了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
typedef long long ll;
using namespace std; const int N = ;
const int MOD = ;
inline int read()
{
int x=;char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x;
}
struct Edge {
int to, next;
} edge[N*];
int head[N];
int edge_cnt; int a[N], sz[N], inv[MOD];
bool used[N];
int root, minsz, size;
int ansx, ansy;
int tmp[N], id[N], cnt;
int mp[MOD];
int n, k; void up(int &x, int y) { if(y>x) x=y; } void query(int v, int x) {
int ser = (ll)k*inv[v]%MOD;
int y = mp[ser];
if (y == || x == y) return ;
if (y < x) swap(x, y);
if (x < ansx ||(x == ansx && y < ansy)) ansx=x, ansy=y;
} void add_edge(int u, int v) {
edge[edge_cnt].to = v;
edge[edge_cnt].next = head[u];
head[u] = edge_cnt++;
} void get_root(int u, int fa) {
sz[u] = ;
int maxn= ;
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (v == fa || used[v]) continue;
get_root(v, u);
sz[u] += sz[v];
up(maxn, sz[v]);
}
up(maxn, size-sz[u]);
if (maxn < minsz) minsz=maxn, root=u;
} void dfs(int u, int fa, int val) {
tmp[cnt] = val; id[cnt++] = u;
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (v == fa || used[v]) continue;
dfs(v, u, (ll)val*a[v]%MOD);
}
} void solve(int u) {
used[u] = true;
mp[ a[u] ] = u;
// 计算经过u的所有乘积为k的点对
// 对每一个子节点处理 防止找的的点对是同一个子树的
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (used[v]) continue;
cnt = ; dfs(v, u, a[v]);
for (int j = ; j < cnt; ++j) query(tmp[j], id[j]);
for (int j = ; j < cnt; ++j) {
tmp[j] = (ll)tmp[j]*a[u]%MOD;
int &now = mp[tmp[j]];
if (now == || now > id[j]) mp[tmp[j]]=id[j];
}
}
// 删除所有记录 因为处理子树内时相互没有影响
mp[a[u]] = ;
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (used[v]) continue;
cnt = ; dfs(v, u, (ll)a[v]*a[u]%MOD);
for (int j = ; j < cnt; ++j) {
mp[tmp[j]] = ;
}
}
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (used[v]) continue;
size = sz[v]; minsz = n+;
get_root(v, );
solve(root);
}
}
int main() { inv[]=;
for(int i=;i<MOD;i++)
{
int a=MOD/i,b=MOD%i;
inv[i]=((ll)inv[b]*(-a)%MOD+MOD)%MOD;
}
while (~scanf("%d%d", &n, &k)) {
for (int i = ; i <= n; ++i) a[i] = read();
int u, v;
memset(head, -, sizeof head);
edge_cnt = ;
memset(used, , sizeof used);
for (int i = ; i < n; ++i) {
u = read(); v = read();
add_edge(u, v);
add_edge(v, u);
}
minsz = n+; size = n;
get_root(, );
ansx = ansy = MOD;
solve(root);
if (ansx == MOD) puts("No solution");
else printf("%d %d\n", ansx, ansy);
}
return ;
}
hdu4812-D Tree (树的点分治)的更多相关文章
- hdu 4812 D Tree(树的点分治)
D Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Total ...
- 【poj1741】Tree 树的点分治
题目描述 Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dis ...
- POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
- 【POJ 1741】 Tree (树的点分治)
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 100 ...
- POJ 1741 Tree(树的点分治,入门题)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 21357 Accepted: 7006 Description ...
- HDU 4670 Cube number on a tree ( 树的点分治 )
题意 : 给你一棵树 . 树的每一个结点都有一个权值 . 问你有多少条路径权值的乘积是一个全然立方数 . 题目中给了你 K 个素数 ( K <= 30 ) , 全部权值都能分解成这k个素数 思路 ...
- HDU4812 D Tree(树的点分治)
题目大概说给一棵有点权的树,输出字典序最小的点对,使这两点间路径上点权的乘积模1000003的结果为k. 树的点分治搞了.因为是点权过根的两条路径的LCA会被重复统计,而注意到1000003是质数,所 ...
- poj 1741 Tree(树的点分治)
poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...
- POJ 1741 Tree 树的分治(点分治)
题目大意:给出一颗无根树和每条边的权值,求出树上两个点之间距离<=k的点的对数. 思路:树的点分治.利用递归和求树的重心来解决这类问题.由于满足题意的点对一共仅仅有两种: 1.在以该节点的子树中 ...
随机推荐
- solr教程,值得刚接触搜索开发人员一看
http://blog.csdn.net/awj3584/article/details/16963525 Solr调研总结 开发类型 全文检索相关开发 Solr版本 4.2 文件内容 本文介绍sol ...
- Coder-Strike 2014 - Round 1(A~E)
题目链接 A. Poster time limit per test:1 secondmemory limit per test:256 megabytesinput:standard inputou ...
- hdu 3927 Math Geek
纯数论题,不解释!!!! 代码如下: #include<stdio.h> int main(){ ,m; scanf("%d",&t); while(t--){ ...
- Android:常见错误提示
记录开发中常出现的错误 1.遇到这样的错误时,应该立马想到是书写错误或语法错误,常见为android:name写成了name Attribute is missing the Android name ...
- C#基础精华02(静态类,值类型,引用类型,枚举,结构,ref与out)
静态类 静态类不能被其他类继承,静态成员亦不能被继承(访问的是同一个),备注1. 静态类只能继承自Object类.(静态类不能继承自其它类.) 继承(多态).静态本身就是相反的. 静态类不能实现任何接 ...
- Fetching android sdk component information
原文地址: Android Studio安装以及Fetching android sdk component information超时的解决方案 - sonyi - 博客园 http://www.c ...
- 对Cost (%CPU) 粗略的理解
今天研究执行计划,看到执行计划里面有Cost (%CPU),我这边研究了一把,不知道对与否,拿出来晒晒 在Oracle 10g中,Oracle 把CPU的cost也统计在执行计划中去了, 这和以前的8 ...
- TCP/IP的三次握手和四次分手以及超时机制
使用INADDR_ANY的时候,往往针对多网卡情况,采用tcp连接方式,需要选择使用哪一个网卡发送,自己猜想应该是使用三次握手机制,如何判断目标地址不可达,应该使用的是超时机制,即握手超时则不可到达. ...
- 【原创】oracle的tpc-c测试及方法
大家好,很高兴来到博客园分享自己的所见所得.希望和大家多多交流,共同进步. 本文重点在于简介使用BenchmarkSQL对oracle进行tpcc的测试步骤,只是一个简单入门的过程. 开源测试工具:B ...
- WinAPI—— CallNextHookEx调用下一个钩子
CallNextHookEx( hhk: HHOOK; {当前钩子的句柄} nCode: Integer; {钩子代码; 就是给下一个钩子要交待的} wParam: WPARAM; ...