逆元链接:https://www.cnblogs.com/zzqc/p/7192436.html

经典的树分治题

#pragma comment("linker,"/STACK:102400000,102400000)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 100005
#define mod 1000003
typedef long long ll
struct E{
int v,d,next;
E(){}
E(int vv,int nn):v(vv),next(nn){}
}e[MAXN<<];
bool vis[MAXN];
int size,head[MAXN],ans[];//边和答案
int flag[mod],F[mod],id[MAXN];//哈希
ll ni[mod];//1-mod之间的逆元表
int sum[MAXN],mi,cr;//cr是子树的路径数量
ll val[MAXN],path[MAXN];//点权路径
void init(){
size=;
memset(vis,,sizeof vis);
memset(ans,-,sizeof ans);
memset(head,-,sizeof head);
memset(flag,,sizeof flag);
}
void add(int u,int v){
e[size]=E(v,head[u]);
head[u]=size++;
}
//这个函数找路径
void dfs(int u,ll k){
int i,v;
sum[u]=;
vis[u]=true;
id[cr]=u;
path[cr++]=k*val[u]%mod;
ll tmp=path[cr-];
for(i=head[u];i!=-;i=e[i].next){
v=e[i].v;
if(vis[v]) continue;
dfs(v,tm);
sum[u]+=sum[v];
}
vis[u]=false;
}
ll k;
int n,ca;
void getans(int a,int b){
if(a>b) swap(a,b);
if(ans[]==- || ans[]>a)
ans[]=a,ans[]=b;
else if(ans[]==a && ans[]>b)
ans[]=b;
}
//找重心
void getroot(int u){
int i,v,mx=;
sum[u]=;
vis[u]=true;
for(i=head[u];i!=-;i=e[i].next){
v=e[i].v;
if(vis[v]) continue;
getroot(v);
sum[u]+=sum[v];
mx=max(mx,sum[v]);
}
mx=max(mx,sum[]-sum[u]);
if(mx<mi) mi=mx,root=u;
vis[u]=false;
}
void cal(int u,int cnt){
if(cnt==) return;
int i,v,j;
mi=n;
sum[]=cnt;//树规模为cnt
getroot(u);
vis[root]=true;
for(i=head[root];i~=-;i=e[i].next){
v=e[i].v;
if(vis[v]) continue;
cr=;
dfs(v,);
for(j=;j<cr;j++){
if(path[j]*val[root]%mod==k)//直接从根出发
getans(root,id[j]);
ll tmp=k*ni[path[j]*val[root]%mod]%mod;//k*x逆元=y
if(flag[tmp]!=ca) continue;//没有在当前树中找到路径
getans(F[tmp],id[j]);//F[tmp]是值为tmp的path对应的终点编号,id[j]是当前路径的终点编号
}
//把当前子树更新到目前哈希表中
for(j=;j<cr;j++){
int tmp=path[j];
if(flag[tmp]!=ca || F[tmp]>id[j])//如果当前哈希表状态中没有path[j],或者F[tmp]的结点编号没有优化到最小
F[tm]=id[j],flag[tm]=ca;
}
}
ca++;//每次搜完一颗子树,颜色数+1
//这里就是分治
for(i=head[root];i!=-;i=e[i].next){
if(vis[e[i].v])
continue;
cal(e[i].v,sum[e[i].v]);
}
}
//拓展欧几里得打表,求的逆元就是最后的x
ll egcd(ll a,ll b,ll &x,ll &y){
ll temp,tempx;
if(b==){
x=;y=;
return a;
}
temp=egcd(b,a%b,x,y);
tempx=x;
x=y;
y=tempx-a/b*y;
return temp;
}
int main(){
int u,v,i,j;
ll y;
for(i=;i<mod;i++){//拓展欧几里得打表求逆元,也可以递推打表,快速幂打表
egcd(i*1ll,mod*1ll,ni[i],y);
ni[i]%=mod,ni[i]=(ni[i]+mod)%mod;
}
while(scanf("%d%lld",&n,&k)==){
init();
ca=;//不能是0
for(i=;i<=n;i++) scanf("%lld",&val[i]);
for(i=;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
cal(,n);
if(ans[]==-)
puts("No solution");
else
printf("%d %d\n",ans[],ans[]);
}
}

hdu4812 逆元+树分治的更多相关文章

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

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

  2. BZOJ5334 [TJOI2018] 数学计算 【线段树分治】

    题目分析: 大概是考场上的签到题.首先mod不是质数,所以不能求逆元.注意到有加入操作和删除操作.一个很典型的想法就是线段树分治.建立时间线段树然后只更改有影响的节点,最后把所有标记下传.时间复杂度是 ...

  3. HDU 4812 D Tree 树分治

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

  4. hdu-5977 Garden of Eden(树分治)

    题目链接: Garden of Eden Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/ ...

  5. 【BZOJ-1468】Tree 树分治

    1468: Tree Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 534[Submit][Status][Discuss] ...

  6. BZOJ 2152: 聪聪可可 树分治

    2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...

  7. POJ 1741 Tree 树分治

    Tree     Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...

  8. UVALive 7148 LRIP【树分治+线段树】

    题意就是要求一棵树上的最长不下降序列,同时不下降序列的最小值与最大值不超过D. 做法是树分治+线段树,假设树根是x,y是其当前需要处理的子树,对于子树y,需要处理出两个数组MN,MX,MN[i]表示以 ...

  9. BZOJ 2566 xmastree(树分治+multiset)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2566 题意:一棵有边权的树.结点有颜色.每次修改一个点的颜色.求每次修改后所有同色 ...

随机推荐

  1. tomcat配置好后,启动eclipse中的server,不能出现有猫的页面,提示404

    原因:tomcat与eclipse中的server未关联起来 解决办法:双击servers中的server,在Server Locations中选中第二项,保存之后再进行刚才的操作就好了.

  2. JVM总结(二):JVM的内存分配策略

    这节我们总结一下JVM中的内存分配策略.目录如下: 内存分配策略 对象优先在新生代Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保 内存分配策略 Java ...

  3. git使用详细过程

    1. Git概念 1.1. Git库中由三部分组成        Git 仓库就是那个.git 目录,其中存放的是我们所提交的文档索引内容,Git 可基于文档索引内容对其所管理的文档进行内容追踪,从而 ...

  4. 让div固定在顶部不随滚动条滚动【转】

    让div固定在顶部不随滚动条滚动 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...

  5. .NET面试题系列(十五)yong

    Redis为什么使用单进程单线程方式也这么快 Redis遍历所有key的两个命令 -- KEYS 和 SCAN 一致性Hash算法 利用一致性哈希水平拆分MySql单表 单例模式  锁 双重锁 单例模 ...

  6. FastReport报表打印总页数的问题?

    设置两次报表后加入引号内内容 "第[Page#]页 共[TotalPages#]页" 本站文章除注明转载外,均为本站原创或翻译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果 ...

  7. IDEA不生成WAR包,报错

    com.intellij.javaee.oss.admin.jmx.JmxAdminException: com.intellij.execution.ExecutionExceptionProjec ...

  8. angularjs指令中scope参数 true、false、{} 的区别详解

    scope 有三个参数 true.false.{} scope 默认是 false,当 scope设置为true时,会从父作用域继承并创建一个新的作用域对象, 按照true .false的反向思维,我 ...

  9. adb环境变量配置

    针对win10系统: 搜索“高级系统设置”,点击“环境变量”按钮: 找到“path”双击: 双击“path”,在弹出的环境变量列表中新建,填入adb的文件路径 检查配置是否成功,运行命令adb,出现如 ...

  10. B - Birthday Boy Gym - 102007B

    题目链接:https://cn.vjudge.net/contest/283924#problem/B 题目大意:给你n个人的信息,让你找出一个时间,要求让你选择一天,使得这一天的前一个生日距离它最远 ...