D Tree HDU - 4812
https://vjudge.net/problem/HDU-4812
点分就没一道不卡常的?
卡常记录:
1.求逆元忘开longlong
2.把solve中分离各个子树的方法,由“一开始全部加入,处理某个子树前先删除该子树”,变为“逐渐加入,每一次加入某个子树之前处理该子树,不用删除“(由于点对是无序的,只要一个方向处理过就行了,另一个方向不需要处理)
//%:pragma GCC optimize(3)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<set>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
#define md 1000003
struct E
{
int to,nxt;
}e[];
int f1[],ne;
int sz[],fx[],a[],d[];
bool vis[];
int root,sum;pi ans;
set<pi> s;
int inv[];
int n,K;
void getroot(int x,int fa)
{
sz[x]=;fx[x]=;
for(int k=f1[x];k;k=e[k].nxt)
if(!vis[e[k].to]&&e[k].to!=fa)
{
getroot(e[k].to,x);
sz[x]+=sz[e[k].to];
fx[x]=max(fx[x],sz[e[k].to]);
}
fx[x]=max(fx[x],sum-sz[x]);
if(fx[x]<fx[root]) root=x;
}
void getsz(int x,int fa)
{
sz[x]=;
for(int k=f1[x];k;k=e[k].nxt)
if(!vis[e[k].to]&&e[k].to!=fa)
{
getsz(e[k].to,x);
sz[x]+=sz[e[k].to];
}
}
void getd(int u,int fa)
{
for(int k=f1[u];k;k=e[k].nxt)
if(!vis[e[k].to]&&e[k].to!=fa)
{
d[e[k].to]=ll(d[u])*a[e[k].to]%md;
getd(e[k].to,u);
}
}
void addd(int u,int fa)
{
s.insert(mp(d[u],u));
for(int k=f1[u];k;k=e[k].nxt)
if(!vis[e[k].to]&&e[k].to!=fa)
addd(e[k].to,u);
}
void deld(int u,int fa)
{
s.erase(mp(d[u],u));
for(int k=f1[u];k;k=e[k].nxt)
if(!vis[e[k].to]&&e[k].to!=fa)
deld(e[k].to,u);
}
void calc(int u,int fa)
{
int t=ll(K)*inv[ll(d[u])*a[root]%md]%md;
auto it=s.lower_bound(mp(t,));
if(it!=s.end()&&it->fi==t)
{
int a=u,b=it->se;
if(a>b) swap(a,b);
ans=min(ans,mp(a,b));
}
for(int k=f1[u];k;k=e[k].nxt)
if(!vis[e[k].to]&&e[k].to!=fa)
calc(e[k].to,u);
}
void solve(int u)
{
s.clear();d[u]=;s.insert(mp(,u));vis[u]=;
for(int k=f1[u];k;k=e[k].nxt)
if(!vis[e[k].to])
{
d[e[k].to]=a[e[k].to];getd(e[k].to,u);
calc(e[k].to,u);
addd(e[k].to,u);
}
for(int k=f1[u];k;k=e[k].nxt)
if(!vis[e[k].to])
{
root=;
getsz(e[k].to,);sum=sz[e[k].to];
getroot(e[k].to,);
solve(root);
}
}
int main()
{
int i,x,y;
inv[]=;
for(i=;i<=;i++) inv[i]=ll(md-md/i)*inv[md%i]%md;
fx[]=0x3f3f3f3f;
while(scanf("%d%d",&n,&K)==)
{
for(i=;i<=n;i++) f1[i]=vis[i]=;
ne=;ans=mp(n+,n+);
for(i=;i<=n;i++) scanf("%d",&a[i]);
for(i=;i<n;i++)
{
scanf("%d%d",&x,&y);
e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;
e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;
}
root=;sum=n;getroot(,);
solve(root);
if(ans==mp(n+,n+)) puts("No solution");
else printf("%d %d\n",ans.fi,ans.se);
}
return ;
}
D Tree HDU - 4812的更多相关文章
- E - D Tree HDU - 4812 点分治+逆元
这道题非常巧妙!!! 我们进行点分治的时候,算出当前子节点的所有子树中的节点,到当前节点节点的儿子节点的距离,如下图意思就是 当前节点的红色节点,我们要求出红色节点的儿子节点绿色节点,所有绿色的子树节 ...
- HDU 4812 D Tree
HDU 4812 思路: 点分治 先预处理好1e6 + 3以内到逆元 然后用map 映射以分治点为起点的链的值a 成他的下标 u 然后暴力跑出以分治点儿子为起点的链的值b,然后在map里查找inv[b ...
- hdu 4812 DTree (点分治)
D Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total S ...
- H - Partial Tree HDU - 5534 (背包)
题目链接: H - Partial Tree HDU - 5534 题目大意:首先是T组测试样例,然后n个点,然后给你度数分别为(1~n-1)对应的不同的权值,然后问你在这些点形成树的前提下的所能形 ...
- Binary Tree HDU - 5573 (思维)
题目链接: B - Binary Tree HDU - 5573 题目大意: 给定一颗二叉树,根结点权值为1,左孩子权值是父节点的两倍,右孩子是两倍+1: 给定 n 和 k,让你找一条从根结点走到第 ...
- Minimal Ratio Tree HDU - 2489
Minimal Ratio Tree HDU - 2489 暴力枚举点,然后跑最小生成树得到这些点时的最小边权之和. 由于枚举的时候本来就是按照字典序的,不需要额外判. 错误原因:要求输出的结尾不能有 ...
- Color a Tree HDU - 6241
/* 十分巧妙的二分 题意选最少的点涂色 使得满足输入信息: 1 x的子树涂色数不少于y 2 x的子树外面涂色数不少于y 我们若是把2转化到子树内最多涂色多少 就可以维护这个最小和最大 如果我们二分出 ...
- S - Query on a tree HDU - 3804 线段树+dfs序
S - Query on a tree HDU - 3804 离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...
- HDU - 4812 D Tree 点分治
http://acm.hdu.edu.cn/showproblem.php?pid=4812 题意:有一棵树,每个点有一个权值要求找最小的一对点,路径上的乘积mod1e6+3为k 题解:点分治,挨个把 ...
随机推荐
- SQL 通配符及其使用
Sql Server中通配符的使用 通配符_ "_"号表示任意单个字符,该符号只能匹配一个字符."_"可以放在查询条件的任意位置,且只能代表一个字符.一个汉字只 ...
- 【php】读取"文件列表"按时间倒序显示,并递归显示各层文件夹、!
思路: 1.读取该php所在文件夹的文件列表,用"改动时间.文件名称"做键值对,塞入数组.对"改动时间"倒序.(貌似不能直接按时间倒序读取文件列表,此处为间接方 ...
- HDU 6155 Subsequence Count 线段树维护矩阵
Subsequence Count Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Oth ...
- UR#34. 多项式乘法
#34. 多项式乘法 统计 描述 提交 自定义测试 这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+ ...
- 微信小程序存放视频文件到阿里云用到算法js脚本文件
peterhuang007/weixinFileToaliyun: 微信小程序存放视频文件到阿里云用到算法js脚本文件 https://github.com/peterhuang007/ ...
- RubyMine安装、破解
经常安装东西,这是我安装过最快的ide破解版. 下载地址: http://www.jetbrains.com/ruby/download/index.html 破解序列号: name: rubymin ...
- linux 查看权限
参考文章:http://www.linuxidc.com/Linux/2014-10/108114.htm Linux文件访问权限分为可读,可写和可执行三种. 可用ls -l命令查看,例: ls -l ...
- IE67下float左右对齐
例子: <style> .h1{text-align: left;} .leftA{color: #000} .rightA{color: #ccc; float: right;} < ...
- java android 将 List中元素互换位置
很多时候我要对List中的元素调换位置,这时候可以用如下代码,意思是将data中的index1与index2元素互换位置 //data 为List Collections.swap(data,inde ...
- html5--3.2 input元素(2)
html5--3.2 input元素(2) 学习要点 input元素及其属性 input元素 用来设置表单中的内容项,比如输入内容的文本框,按钮等 不仅可以布置在表单中,也可以在表单之外的元素使用 i ...