D Tree

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 3876    Accepted Submission(s): 743

Problem Description
There is a skyscraping tree standing on the playground of Nanjing University of Science and Technology. On each branch of the tree is an integer (The tree can be treated as a connected graph with N vertices, while each branch can be treated as a vertex). Today the students under the tree are considering a problem: Can we find such a chain on the tree so that the multiplication of all integers on the chain (mod 106 + 3) equals to K?
Can you help them in solving this problem?
 
Input
There are several test cases, please process till EOF.
Each test case starts with a line containing two integers N(1 <= N <= 105) and K(0 <=K < 106 + 3). The following line contains n numbers vi(1 <= vi < 106 + 3), where vi indicates the integer on vertex i. Then follows N - 1 lines. Each line contains two integers x and y, representing an undirected edge between vertex x and vertex y.
 
Output
For each test case, print a single line containing two integers a and b (where a < b), representing the two endpoints of the chain. If multiply solutions exist, please print the lexicographically smallest one. In case no solution exists, print “No solution”(without quotes) instead.
For more information, please refer to the Sample Output below.
 
Sample Input
5 60
2 5 2 3 3
1 2
1 3
2 4
2 5
5 2
2 5 2 3 3
1 2
1 3
2 4
2 5
 
Sample Output
3 4
No solution
/*
hdu 4812 DTree (点分治) problem:
求最小的点对使 u->v的点权的乘积%mod=limit. solve:
每次求过当前树根节点的情况. 每次可以计算出 一点到当前根节点的情况temp,所以只需要找出其它子树中是否有limit/temp
因为有取余,所以先预处理出所有的逆元. hhh-2016-08-23 10:52:26
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <map>
#define lson i<<1
#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define key_val ch[ch[root][1]][0]
#define inf 0x3FFFFFFFFFFFFFFFLL
#define mod 1000003
using namespace std;
const int maxn = 100010;
ll val[maxn],d[maxn],limit;
int head[maxn];
int n,k,s[maxn],f[maxn],root;
int Size,tot;
bool vis[maxn];
vector<ll> ta; struct node
{
int to,w,next;
}edge[maxn<<2]; void add_edge(int u,int v)
{
edge[tot].to=v,edge[tot].next=head[u],head[u]=tot++;
} void get_root(int now,int fa)
{
int v;
s[now] = 1,f[now] = 0;
for(int i = head[now];~i;i = edge[i].next)
{
if( (v=edge[i].to) == fa || vis[v])
continue;
get_root(v,now);
s[now] += s[v];
f[now] = max(f[now],s[v]);
}
f[now] = max(f[now],Size - s[now]);
if(f[now] < f[root]) root = now;
}
int id[maxn];
int idnum;
void dfs(int now,int fa)
{
int v;
ta.push_back(d[now]);
id[idnum++] = now;
s[now] = 1;
for(int i = head[now];~i;i = edge[i].next)
{
if( (v=edge[i].to) == fa || vis[v])
continue;
d[v] = (d[now] * val[v])%mod;
dfs(v,now);
s[now] += s[v];
}
}
int flag[mod + 10];
int mp[mod + 10];
int cur = 0;
ll ni[mod+10];
int ans[2];
void to_ans(int a, int b)
{ if (a > b) swap(a,b);
if (ans[0] == -1 || ans[0] > a) ans[0] = a, ans[1] = b;
else if (ans[0] == a && ans[1] > b) ans[1] = b;
// cout <<"a:"<<ans[0] << " b:" <<ans[1] <<endl;
} void work(int now,int cnt)
{
f[0] = Size = cnt;
get_root(now,root = 0);
int v;
vis[root] = 1;
for(int i = head[root];~i;i = edge[i].next)
{
if(!vis[v = edge[i].to])
{
ta.clear(),d[v] = val[v],idnum = 0;
dfs(v,0); for(int j = 0; j < ta.size();j++)
{
if(val[root]*ta[j] % mod == limit && root != id[j])
to_ans(root,id[j]);
ll t = (ll)limit*ni[val[root]*ta[j]%mod]%mod;
if(flag[t] != cur)
continue;
if(mp[t] == id[j])
continue;
to_ans(mp[t],id[j]);
}
for(int j = 0; j < ta.size(); j++)
{
int t = ta[j];
if(flag[t] != cur || mp[t] > id[j]) mp[t] = id[j],flag[t] = cur;
}
}
}
cur ++;
for(int i = head[root];~i;i = edge[i].next)
{
if(vis[edge[i].to])
continue;
work(edge[i].to,s[edge[i].to]);
}
} ll egcd(ll a,ll b, ll &x, ll &y)
{
ll temp,tempx;
if (b == 0)
{
x = 1;
y = 0;
return a;
}
temp = egcd(b,a % b, x, y);
tempx = x;
x = y;
y = tempx - a / b * y;
return temp;
} int main()
{ ll y;
for (int i = 0; i < mod; i++)
{
egcd(i*1ll, mod*1ll, ni[i], y);
ni[i] %= mod, ni[i] = (ni[i]+mod)%mod;
}
while(scanf("%d%I64d",&n,&limit)!=EOF)
{
if(!n && !limit)
break;
clr(vis,0),clr(flag,0);
clr(head,-1),tot = 0;
ans[0] = ans[1] = -1;
int a,b;
for(int i = 1; i <= n; i++)
{
scanf("%I64d",&val[i]);
}
for(int i = 1; i < n; i++)
{
scanf("%d%d",&a,&b);
add_edge(a,b);
add_edge(b,a);
}
cur = 1;
work(1,n);
if(ans[0] == -1)
printf("No solution\n");
else
printf("%d %d\n",ans[0],ans[1]);
}
return 0;
}

  

hdu 4812 DTree (点分治)的更多相关文章

  1. HDU 4812 D Tree

    HDU 4812 思路: 点分治 先预处理好1e6 + 3以内到逆元 然后用map 映射以分治点为起点的链的值a 成他的下标 u 然后暴力跑出以分治点儿子为起点的链的值b,然后在map里查找inv[b ...

  2. hdu 5830 FFT + cdq分治

    Shell Necklace Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  3. HDU - 4812 D Tree 点分治

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

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

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

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

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

  6. HDU 4812 D Tree 树分治

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

  7. HDU 4812 (点分治)

    题目:https://vjudge.net/contest/307753#problem/E 题意:给你一颗树,树上每个点都有个权值,现在问你是否存在 一条路径的乘积 mod 1e6+3  等于 k的 ...

  8. E - D Tree HDU - 4812 点分治+逆元

    这道题非常巧妙!!! 我们进行点分治的时候,算出当前子节点的所有子树中的节点,到当前节点节点的儿子节点的距离,如下图意思就是 当前节点的红色节点,我们要求出红色节点的儿子节点绿色节点,所有绿色的子树节 ...

  9. HDU 4812:D Tree(树上点分治+逆元)

    题目链接 题意 给一棵树,每个点上有一个权值,问是否存在一条路径(不能是单个点)上的所有点相乘并对1e6+3取模等于k,输出路径的两个端点.如果存在多组答案,输出字典序小的点对. 思路 首先,(a * ...

随机推荐

  1. Argparse简易教程

    Argparse简易教程 原文:Argparse Tutorial 译者:likebeta 本教程是对于Python标准库中推荐使用的命令行解析模块argparse的简单介绍. PS:还有其他两个模块 ...

  2. Angular-ui-router+ocLazyLoad.js应用实例

    AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Goole所收购.是一款优秀的前端JS框架.AngularJS有着诸多特性,最为核心的是:MVC,撗块化,自动化双向数据绑 ...

  3. day-6 机器学习概念及应用

    学习玩Python基础语法,今天开始进行机器学习,首先了解下机器学习和深度学习的一些基本概念和术语: 1.  机器学习概念及应用 2.  深度学习概念及应用 3.  机器学习基本术语及举例 4.  机 ...

  4. Docker学习笔记 - Docker客户端和服务端

    学习内容: Docker客户端和服务端的通讯方式:client和自定义程序 Docker客户端和服务端的连接方式:socket 演示Docker客户端和服务端之间用remote-api通讯:nc   ...

  5. 新概念英语(1-53)An interesting climate

    新概念英语(1-53)An interesting  climate What's the favourite subject of conversation in England? A:Where ...

  6. maven入门(1-1)maven是什么?

    Maven是一个项目管理工具,它包含了 一个项目对象模型 (Project Object Model), 一组标准集合, 一个项目生命周期(Project Lifecycle), 一个依赖管理系统(D ...

  7. ssh_maven之controller层开发

    我们已经完成了前两层的开发,现在 只剩下我们的controller层了,对于这一层,我们需要创建一个动作类CustomerAction,另外就是我们的strutss.xml以及我们的applicati ...

  8. spring3——IOC之基于XML的依赖注入(DI )

    我们知道spring容器的作用是负责对象的创建和对象间关系的维护,在上一篇博客中我们讲到spring容器会先调用对象的无参构造方法创建一个空值对象,那么接下来容器就会对对象的属性进行初始化,这个初始化 ...

  9. hdu1003 Max Sum---最大子段和+记录开始结束点

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1003 题目大意: 求最大子段和,并且输出最大子段和的起始位置和终止位置. 思路: 根据最大子段和基本 ...

  10. 极速下载百度网盘-吴水成老师的-dubbo课程

    极速下载百度网盘-吴水成老师的-dubbo课程,极速下载百度网盘-吴水成老师的-dubbo课程,极速下载百度网盘-吴水成老师的-dubbo课程,极速下载百度网盘-吴水成老师的-dubbo课程 先看主目 ...