zoukankan      html  css  js  c++  java
  • HDU4812 D Tree

    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?

    InputThere 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.OutputFor 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")

    树 点分治

      自己想到了点分治,自己想到了逆元,自己想到了更新答案的方法,然后TLE到飞起,去看了别人的题解才发现没有初始化邻接表,真是感人至深。

    其实就是个比较普通的点分治,把已经处理的链的结果存到map里(直接用数组就好),在处理新结点的时候匹配map里的值。

    需要注意的是在mod意义下找乘积为K的点,需要求逆元。逆元递推式见代码

      1 /*by SilverN*/
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<vector>
      8 #include<map>
      9 #define LL long long
     10 using namespace std;
     11 const int mod=1e6+3;
     12 const int mxn=120010;
     13 int read(){
     14     int x=0,f=1;char ch=getchar();
     15     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     16     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 struct edge{int v,nxt;}e[mxn<<1];
     20 int hd[mxn],mct=0;
     21 void add_edge(int u,int v){e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;}
     22 int n,K;
     23 LL w[mxn];
     24 //
     25 int mc[mxn],sz[mxn],rt,smm;
     26 LL dis[mxn];
     27 bool vis[mxn];
     28 //map<int,int>mp;
     29 int mp[mxn*11];
     30 //
     31 LL inv[mxn*11];
     32 void init(){
     33     inv[1]=1;
     34     for(int i=2;i<mod;i++){
     35         inv[i]=((-mod/i)*inv[mod%i]%mod+mod)%mod;
     36     }
     37     return;
     38 }
     39 void DFS_sz(int u,int fa){
     40     sz[u]=1;mc[u]=0;
     41     for(int i=hd[u];i;i=e[i].nxt){
     42         if(e[i].v==fa || vis[e[i].v])continue;
     43         int v=e[i].v;
     44         DFS_sz(v,u);
     45         sz[u]+=sz[v];
     46         mc[u]=max(mc[u],sz[v]);
     47     }
     48     mc[u]=max(mc[u],smm-mc[u]);
     49     if(mc[u]<mc[rt])rt=u;
     50     return;
     51 }
     52 int st[mxn],top=0;
     53 int ans[2];
     54 inline void upd(int x,int y){
     55     if(x>y)swap(x,y);
     56     if(!ans[0] || ans[0]>x || (ans[0]==x && ans[1]>y)){
     57         ans[0]=x;ans[1]=y;
     58     }
     59     return;
     60 }
     61 void clc(int u,int fa,int mode){
     62     if(!mode){    
     63         LL tmp=(K*inv[dis[u]]%mod+mod)%mod;
     64         if(mp[tmp]){    upd(u,mp[tmp]);    }
     65     }
     66     else{
     67         if(!mp[dis[u]]){mp[dis[u]]=u;st[++top]=dis[u];}
     68         else mp[dis[u]]=min(mp[dis[u]],u);
     69     }
     70     for(int i=hd[u];i;i=e[i].nxt){
     71         if(e[i].v==fa || vis[e[i].v])continue;
     72         int v=e[i].v;
     73         dis[v]=dis[u]*w[v]%mod;
     74         clc(v,u,mode);
     75     }
     76     return;
     77 }
     78 void solve(int x){
     79     vis[x]=1;
     80     mp[w[x]]=x;
     81     for(int i=hd[x];i;i=e[i].nxt){
     82         if(vis[e[i].v])continue;
     83         int v=e[i].v;
     84         dis[v]=w[v]%mod;
     85         clc(v,x,0);
     86         dis[v]=w[x]*w[v]%mod;
     87         clc(v,x,1);
     88     }
     89     while(top){
     90         mp[st[top--]]=0;
     91     }
     92     mp[w[x]]=0;
     93     for(int i=hd[x];i;i=e[i].nxt){
     94         if(vis[e[i].v])continue;int v=e[i].v;
     95         smm=sz[v];
     96         rt=0;
     97         DFS_sz(v,0);
     98         solve(rt);
     99     }
    100     return;
    101 }
    102 int main(){
    103     int i,j,u,v;
    104     init();
    105     while(scanf("%d%d",&n,&K)!=EOF){
    106         memset(hd,0,sizeof hd);mct=0;
    107         memset(vis,0,sizeof vis);
    108         ans[0]=ans[1]=0;
    109         for(i=1;i<=n;i++)w[i]=read();
    110         for(i=1;i<n;i++){
    111             u=read();v=read();
    112             add_edge(u,v);
    113             add_edge(v,u);
    114         }
    115         ans[0]=ans[1]=0;
    116         smm=n;mc[rt=0]=mod;
    117         DFS_sz(1,0);
    118         solve(rt);
    119         if(!ans[0])printf("No solution
    ");
    120         else printf("%d %d
    ",ans[0],ans[1]);
    121     }
    122     return 0;
    123 }
    本文为博主原创文章,转载请注明出处。
  • 相关阅读:
    关于添加“服务引用”和“添加引用”的一点总结
    nodejs+express工程 在npm install之后或使用npm install bootstrap命令安装bootstrap之后
    Mongo基础使用,以及在Express项目中使用Mongoose
    Express URL跳转(重定向)的实现
    node 开发web 登陆功能
    node js实战:带数据库,加密的注册登录表单
    nodejs 进阶:封装所有对数据库的常用操作
    nodejs进阶:密码加盐:随机盐值
    Nodejs进阶:密码加盐
    express 路由能力
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6502460.html
Copyright © 2011-2022 走看看