hdu 4812 D Tree(树的点分治)

简介:

D Tree

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


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 10 6 + 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 <= 10 5) and K(0 <=K < 10 6 + 3). The following line contains n numbers v i(1 <= v i < 10 6 + 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
Hint
1. “please print the lexicographically smallest one.”是指: 先依照第一个数字的大小进行比較,若第一个数字大小同样,则依照第二个数字大小进行比較,依次类推。 2. 若出现栈溢出,推荐使用C++语言提交。并通过下面方式扩栈: #pragma comment(linker,"/STACK:102400000,102400000")
 

Source
 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:   5068  5067  5065  5064  5062 
  题意:
给你一个n(1e5)个结点的数。每一个结点有个权值v(1 <= vi < 106 + 3).问你是否存在一条路径u->v。

使得路径上的结点的乘积为k(0 <=K < 106 + 3).有多解输出字典序最小的解。

思路:
先找树的重心。再按树的重心分治。计算子树全部结点到分治重心路径权值的乘积val。再查询hash表看有没有k*inv[val]存在。有就更新答案。分治完一颗子树后再更新hash表。

具体见代码:
#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdio.h>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=100010;
const int mod=1e6+3;
typedef long long ll;
ll inv[mod+10];
int val[maxn],ms[maxn],son[maxn],vis[maxn],cnt,kv;
int mp[mod+10],use[mod+10],ptr,pos,ans1,ans2;
struct node
{
    int v;
    node *next;
} ed[maxn<<1],*head[maxn];
void adde(int u,int v)
{
    ed[cnt].v=v;
    ed[cnt].next=head[u];
    head[u]=&ed[cnt++];
}
void dfs(int fa,int u)
{
    son[u]=1;
    ms[u]=0;
    for(node *p=head[u];p!=NULL;p=p->next)
    {
        if(p->v==fa||vis[p->v])
            continue;
        dfs(u,p->v);
        son[u]+=son[p->v];
        ms[u]=max(ms[u],son[p->v]);
    }
}
void findroot(int fa,int u,int all)
{
    ms[u]=max(ms[u],all-son[u]);
    if(ms[u]<ms[pos])
        pos=u;
    for(node *p=head[u];p!=NULL;p=p->next)
    {
        if(p->v==fa||vis[p->v])
            continue;
        findroot(u,p->v,all);
    }
}
void getroot(int u)
{
    dfs(-1,u);
    pos=u;
    findroot(-1,u,son[u]);
}
void cal(int fa,int u,int mc)//计算答案
{
    mc=(ll)mc*val[u]%mod;
    int op=(ll)kv*inv[mc]%mod,a,b;
    if(mp[op])
    {
        a=u,b=mp[op];
        if(a>b)
            swap(a,b);
        if(a<ans1)
            ans1=a,ans2=b;
        else if(a==ans1&&b<ans2)
            ans2=b;
    }
    for(node *p=head[u];p!=NULL;p=p->next)
    {
        if(p->v==fa||vis[p->v])
            continue;
        cal(u,p->v,mc);
    }
}
void update(int fa,int u,int mc)//更新hash表
{
    mc=(ll)mc*val[u]%mod;
    if(!mp[mc])
        use[ptr++]=mc,mp[mc]=u;
    else
        mp[mc]=min(mp[mc],u);
    for(node *p=head[u];p!=NULL;p=p->next)
    {
        if(p->v==fa||vis[p->v])
            continue;
        update(u,p->v,mc);
    }
}
void solve(int u)//每次处理一颗子树
{
    int root,i;
    getroot(u);
    root=pos;
    mp[val[root]]=root;
    vis[root]=1,ptr=0;
    for(node *p=head[root];p!=NULL;p=p->next)
    {
        if(vis[p->v])
            continue;
        cal(root,p->v,1);//计算子树路径
        update(root,p->v,val[root]);
    }
    for(i=0;i<ptr;i++)
        mp[use[i]]=0;
    mp[val[root]]=0;
    for(node *p=head[root];p!=NULL;p=p->next)
    {
        if(vis[p->v])
            continue;
        solve(p->v);
    }
}
int main()
{
    int n,i,u,v;
    inv[1]=1;
    for(i=2;i<mod;i++)//预处理逆元
        inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    while(~scanf("%d%d",&n,&kv))
    {
        for(i=1;i<=n;i++)
            scanf("%d",&val[i]);
        memset(head,0,sizeof head);
        memset(vis,0,sizeof vis);
        cnt=0;
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            adde(u,v);
            adde(v,u);
        }
        ans1=ans2=INF;
        solve(1);
        if(ans1!=INF)
            printf("%d %d\n",ans1,ans2);
        else
            printf("No solution\n");
    }
    return 0;
}





本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5144642.html,如需转载请自行联系原作者
相关文章
|
索引
Google Earth Engine(GEE)——提取指定矢量集合中的NDVI值并附时间属性
Google Earth Engine(GEE)——提取指定矢量集合中的NDVI值并附时间属性
378 2
|
传感器 5G UED
5G 标准化进程|带你读《5G空口特性与关键技术》之二
从 2016 年起,3GPP 启动了 R14 研究项,目标是在 2020 年实现 5G 的商业化部署。为此,3GPP 采取了按阶段定义规范的方式。第一阶段目标是R15,旨在完成规范 5G 的有限功能。第二阶段是 R16,旨在完成规范 IMT-2020 所定义的所有功能,将于 2019 年年底到 2020 年完成。
5G 标准化进程|带你读《5G空口特性与关键技术》之二
|
算法 开发者 索引
二分算法详解
本文介绍了二分查找及其相关问题的解决方法,包括基本的二分查找、查找元素的第一个和最后一个位置、求平方根、搜索插入位置、寻找峰值和旋转数组中的最小值等问题。通过详细分析每种情况下的二分查找策略,如循环条件、区间划分及特殊情况处理,提供了清晰的代码实现。适用于算法初学者和需要巩固二分查找技巧的开发者。
436 18
二分算法详解
|
8月前
|
机器学习/深度学习
阿里妈妈首提AIGB并实现大规模商业化落地,将在NeurIPS 2024正式开源Benchmark
阿里妈妈提出AI-Generated Bidding(AIGB)新范式及DiffBid生成式竞价模型,突破传统基于强化学习的自动竞价方法局限。AIGB将自动竞价视为生成问题,通过捕捉复杂依赖关系,提升长期规划和随机环境中的稳定性和效果。DiffBid基于条件扩散建模,灵活生成满足特定目标的竞价轨迹,显著提升GMV和ROI。实验结果表明,DiffBid实现了2.81%的GMV增长和3.36%的ROI增长。然而,生成式建模的复杂性也带来了训练和调优的挑战。 论文链接:https://arxiv.org/abs/2405.16141
337 9
好看简单的Login登录界面,背景色带渐变
好看简单的Login登录界面,背景色带渐变
551 2
|
存储 数据管理 jenkins
自动化测试框架的搭建与实践
【8月更文挑战第3天】随着软件行业的迅猛发展,自动化测试已成为保证软件质量的重要手段。本文将介绍如何搭建一个高效的自动化测试框架,并通过实际代码示例展示其应用。我们将探讨框架设计的核心原则、工具选择和脚本编写的最佳实践,以及如何通过持续集成实现自动化测试流程的优化。
255 1
|
缓存 JavaScript 前端开发
Windows7压缩包安装node.js 报错提示windows Server 2012 R2 和安装React脚手架 最详细教程
对于Windows 7安装node.js 提示“This application is only supported on wWindows 8.1,windows Server 2012 R2, or higher.”类似这种情况的,该问题是因为node.js官方在 x12版本后就不支持win7系统了。
|
安全 算法 测试技术
什么是灰盒测试?
什么是灰盒测试?
1033 1
|
设计模式 前端开发 JavaScript
React开发的设计模式及原则
设计模式是最常见的,通用问题的可复用解决方案的归纳总结,通常被认为是解决该类问题的最佳实践,使用设计模式能帮助我们写出更容易维护,更健壮的代码。设计模式有很多,通常它们都会遵循一些共同的设计原则,接下来我们一起回顾下React社区里出现过的一些设计模式,以及它们所遵循的设计原则。
48154 6
React开发的设计模式及原则
|
运维 前端开发 JavaScript
基于SpringBoot框架的EMR电子病历系统源码
电子病历是信息化建设的重要组成部分,也是医疗质量管理的重要依据之一。完整、及时、高质量的电子病历不仅可以促进医疗质量管理精细化,更可为提高公共卫生质量提供重要参考。电子病历系统采用前后端分离模式开发和部署。B/S版电子病历系统,支持电子病历四级,云HIS与电子病历系统均拥有自主知识产权依据。
633 0
基于SpringBoot框架的EMR电子病历系统源码