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的更多相关文章

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

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

  2. HDU 4812 D Tree

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

  3. hdu 4812 DTree (点分治)

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

  4. H - Partial Tree HDU - 5534 (背包)

    题目链接: H - Partial Tree  HDU - 5534 题目大意:首先是T组测试样例,然后n个点,然后给你度数分别为(1~n-1)对应的不同的权值,然后问你在这些点形成树的前提下的所能形 ...

  5. Binary Tree HDU - 5573 (思维)

    题目链接: B - Binary Tree  HDU - 5573 题目大意: 给定一颗二叉树,根结点权值为1,左孩子权值是父节点的两倍,右孩子是两倍+1: 给定 n 和 k,让你找一条从根结点走到第 ...

  6. Minimal Ratio Tree HDU - 2489

    Minimal Ratio Tree HDU - 2489 暴力枚举点,然后跑最小生成树得到这些点时的最小边权之和. 由于枚举的时候本来就是按照字典序的,不需要额外判. 错误原因:要求输出的结尾不能有 ...

  7. Color a Tree HDU - 6241

    /* 十分巧妙的二分 题意选最少的点涂色 使得满足输入信息: 1 x的子树涂色数不少于y 2 x的子树外面涂色数不少于y 我们若是把2转化到子树内最多涂色多少 就可以维护这个最小和最大 如果我们二分出 ...

  8. S - Query on a tree HDU - 3804 线段树+dfs序

    S - Query on a tree HDU - 3804   离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...

  9. HDU - 4812 D Tree 点分治

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

随机推荐

  1. linux PC手把手搭建minigui3.0开发环境

    1.下载网址http://www.minigui.com/en/download/ 2.下载资料: 3.安装过程: (1)安装 libminigui-gpl-3.0.12.tar.gz tar zxv ...

  2. Session Timeout 与 $.ajaxSetup

    对于session过期跳转的问题,很简单,就是一个过滤器,然后判断session为空?跳转:继续.但是对于ajax的请求,需要做特殊处理,见下面代码中的 // 此处考虑ajax操作session过期的 ...

  3. file类简单操作

    file类可表示文件或文件夹 import java.io.File; import java.io.FilenameFilter; import java.io.IOException; impor ...

  4. iOS中区分照片的来源

    原理就是通过枚举出每个assets group,然后取得group property,group property是个整数,对应头文件中的一些枚举值.用这个可以判断照片是从哪来的(相机胶卷.照片流.相 ...

  5. kbmMW实现sql查询(图文并茂)

    kbmMW对于Delphi来说,是最好的多层框架,没有之一,无论是效率.稳定及架构都让人无可挑剔,尤其自Delphi支持跨平台开发以来,随着Delphi支持ios及Android移动开发,KbmMW也 ...

  6. SpringMVC配置环境

    一,lib目录下加入spring一般所需的jar包 二,配置web.xml <?xml version="1.0" encoding="UTF-8"?&g ...

  7. 不用打开Eclipse就可以执行的命令

    1.android 弹出Android SDK and AVD Manager2.android list avds 列出所有创建的Android模拟器3.android list targets 列 ...

  8. 自定义custom Tab Bar

    iOS提供的Tab Bar比较简单,我们常常有些别样的需求,此时往往需要自行自定义Tab Bar,如下图所示:                           如图所示,需要在某个页面中添加一个类 ...

  9. iOS 深拷贝、浅拷贝、自定义对象拷贝简介

    copy语法的目的:改变副本的时候,不会影响到源对象: 深拷贝:内容拷贝,会产生新的对象.新对象计数器置为1,源对象计数器不变. 浅拷贝:指针拷贝,不会产生新的对象.源对象计数器+1. 拷贝有下面两个 ...

  10. liunx下的权限详解

    用户组 在linux中的每个用户必须属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念 - 所有者 - 所在组 - 其它组 - 改变用户所在的组 所有者 一般为文件的创建 ...