HDU - 4812 D Tree 点分治
http://acm.hdu.edu.cn/showproblem.php?pid=4812
题意:有一棵树,每个点有一个权值要求找最小的一对点,路径上的乘积mod1e6+3为k
题解:点分治,挨个把子树更新,每次把子树和现有的map里找满足条件的点对,然后更新子树到map里,map维护的是每个到根的乘积值最小的点.
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000003
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
const double eps=1e-6;
const int N=100000+10,maxn=1000000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
struct edge{
int to,Next;
}e[N*2];
int cnt,head[N];
void add(int u,int v)
{
e[cnt].to=v;
e[cnt].Next=head[u];
head[u]=cnt++;
}
int n,k,inv[maxn];
bool vis[N];
int sz[N],zx[N],a[N];
map<int,int>ma;
int x,y;
vector<pair<ll,int> >te;
void init()
{
inv[1]=1;
for(int i=2;i<maxn;i++)
inv[i]=(mod-mod/i)*1ll*inv[mod%i]%mod;
}
void dfssz(int u,int f)
{
sz[u]=1;
for(int i=head[u];~i;i=e[i].Next)
{
int x=e[i].to;
if(x!=f && !vis[x])
{
dfssz(x,u);
sz[u]+=sz[x];
}
}
}
void dfszx(int u,int f,int root,int &ans)
{
zx[u]=sz[root]-sz[u];
for(int i=head[u];~i;i=e[i].Next)
{
int x=e[i].to;
if(x!=f && !vis[x])
{
zx[u]=max(zx[u],sz[x]);
dfszx(x,u,root,ans);
}
}
if(zx[u]<zx[ans])ans=u;
}
int findzx(int root)
{
dfssz(root,-1);
int ans=root;
zx[ans]=inf;
dfszx(root,-1,root,ans);
return ans;
}
void dfs1(int u,int f,int root,ll ans)
{
if(a[root]*ans%mod==k)
{
int xx=root,yy=u;
if(xx>yy)swap(xx,yy);
if(xx<x || (xx==x&&yy<y))x=xx,y=yy;
}
ll te=1ll*k*inv[ans*a[root]%mod]%mod;
if(ma.find(te)!=ma.end())
{
int xx=ma[te],yy=u;
if(xx>yy)swap(xx,yy);
if(xx<x || (xx==x&&yy<y))x=xx,y=yy;
}
for(int i=head[u];~i;i=e[i].Next)
{
int x=e[i].to;
if(x!=f && !vis[x])dfs1(x,u,root,ans*a[x]%mod);
}
}
void dfs2(int u,int f,ll ans)
{
if(ma.find(ans)==ma.end())ma[ans]=u;
else if(u<ma[ans])ma[ans]=u;
for(int i=head[u];~i;i=e[i].Next)
{
int x=e[i].to;
if(x!=f && !vis[x])dfs2(x,u,ans*a[x]%mod);
}
}
void solve(int root)
{
int zx=findzx(root);
ma.clear();
vis[zx]=1;
for(int i=head[zx];~i;i=e[i].Next)
{
int x=e[i].to;
if(!vis[x])
{
te.clear();
dfs1(x,zx,zx,a[x]);
dfs2(x,zx,a[x]);
}
}
for(int i=head[zx];~i;i=e[i].Next)
if(!vis[e[i].to])
solve(e[i].to);
}
int main()
{
init();
while(~scanf("%d%d",&n,&k))
{
cnt=0;
memset(head,-1,sizeof head);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
vis[i]=0;
}
for(int i=1;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);add(b,a);
}
x=n+1,y=n+1;
solve(1);
if(x==n+1)puts("No solution");
else printf("%d %d\n",x,y);
}
return 0;
}
/********************
5 5
2 5 2 3 3
1 2
1 3
2 4
2 5
********************/
HDU - 4812 D Tree 点分治的更多相关文章
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- HDU 4812 D Tree 树分治
题意: 给出一棵树,每个节点上有个权值.要找到一对字典序最小的点对\((u, v)(u < v)\),使得路径\(u \to v\)上所有节点权值的乘积模\(10^6 + 3\)的值为\(k\) ...
- HDU 4812 D Tree
HDU 4812 思路: 点分治 先预处理好1e6 + 3以内到逆元 然后用map 映射以分治点为起点的链的值a 成他的下标 u 然后暴力跑出以分治点儿子为起点的链的值b,然后在map里查找inv[b ...
- 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 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 3842 Machine Works(cdq分治维护凸壳)
题目链接:hdu 3842 Machine Works 详细题解: HDU 3842 Machine Works cdq分治 斜率优化 细节比较多,好好体会一下. 在维护斜率的时候要考虑x1与x2是否 ...
随机推荐
- 升级mac xcode打包证书报错 git 报错
reset tryAgain git 在钥匙串中找不到指定的项 重新配置公钥撕咬 SSH keys An SSH key allows you to establish a secure conne ...
- Wireshark分析之TCP协议(二)
(1)TCP首部格式 源端口: 用来传输数据报的端口 目标端口: 数据包将要发送到的端口 序号: 用来表示一个TCP片段.这个值用来表示数据流中的部分数据没有丢失 确认号: 表示通信中希望从另一 ...
- Optimal Milking---poj2112(多重匹配+Floyd+二分)
题目链接:http://poj.org/problem?id=2112 题意:K个挤奶器(编号1~K),每个挤奶器每天最多供M头奶牛.共有C头奶牛(编号K+1~K+C).挤奶器和奶牛间有不同长度的路. ...
- Python并行编程(十二):进程同步
1.基本概念 多个进程可以协同工作来完成一项任务,通常需要共享数据.所以在多进程之间保持数据的一致性就很重要,需要共享数据协同的进程必须以适当的策略来读写数据.同步原语和线程的库类似. - Lock: ...
- centos 邮件服务 腾讯企业邮箱(免费) 使用iRedmail 需要有公网的centos主机 发邮件协议:smtp 端口25 收邮件协议:pop3 端口110 iredmail安装配置 使用邮箱系统 第三十一节课
centos 邮件服务 腾讯企业邮箱(免费) 使用iRedmail 需要有公网的centos主机 发邮件协议:smtp 端口25 收邮件协议:pop3 端口110 iredmail安装配置 ...
- SaltStack系列(一)之环境部署、命令及配置文件详解
一.SaltStack介绍 1.1 saltstack简介: saltstack是基于python开发的一套C/S架构配置管理工具,它的底层使用ZeroMQ消息队列pub/sub方式通信,使用SSL证 ...
- 调试:Spring AOP执行过程
调试项目:https://github.com/1367356/laboratoryWeb 断点位置 点击查询:http://localhost:9002/queryNews?htmlid=15318 ...
- 实现linux下的ls
实现linux下的ls ls的使用 ls -a 列出文件下所有的文件,包括以"."开头的隐藏文件(linux下文件隐藏文件是以.开头的,如果存在..代表存在着父目录). ls -l ...
- cocos代码研究(23)Widget子类ScrollView学习笔记
基础理论 一个能够被用户触摸滚动的一个层次型布局容器视图,允许其尺寸大于屏幕显示的物理尺寸,其内部维护有一个布局用于水平的或垂直的存放子节点.继承自 Layout,被 ListView 继承. 代码实 ...
- 2017ACM/ICPC Guangxi Invitational Solution
A: A Math Problem 题意:给出一个n,找出有多少个k满足kk <= n 思路: kk的增长很快,当k == 16 的时候就已经超过1e18 了,对于每一次询问,暴力一下就可以 ...