zoukankan      html  css  js  c++  java
  • 【HDOJ4812】D Tree(点分治)

    题意:

    给定一棵 n 个点的树,每个点有权值 Vi

    问是否存在一条路径使得路径上所有点的权值乘积 mod(10^6 + 3) 为 K

    输出路径的首尾标号,若有多解,输出字典序最小的解

    对于100%的数据,有1≤n≤10^5,0≤K≤10^6+2,1≤vi ≤10^6+2

    思路:RYZ作业

    预处理逆元

    哈希路径权值乘积的模数,保存编号用来查询

      1 const mo=1000003;
      2 var head,vet,next,len,flag,son:array[1..210000]of longint;
      3     f:array[0..110000]of longint;
      4     dis,a:array[0..110000]of int64;
      5     q:array[1..110000,1..2]of longint;
      6     exf:array[0..mo]of int64;
      7     hash:array[0..mo]of longint;
      8     n,m,i,j,tot,x,y,z,ans1,ans2,sum,root,top,k:longint;
      9 
     10 procedure add(a,b:longint);
     11 begin
     12  inc(tot);
     13  next[tot]:=head[a];
     14  vet[tot]:=b;
     15  head[a]:=tot;
     16 end;
     17 
     18 function max(x,y:longint):longint;
     19 begin
     20  if x>y then exit(x);
     21  exit(y);
     22 end;
     23 
     24 procedure swap(var x,y:longint);
     25 var t:longint;
     26 begin
     27  t:=x; x:=y; y:=t;
     28 end;
     29 
     30 function getroot(u,fa:longint):longint;
     31 var e,v:longint;
     32 begin
     33  son[u]:=1; f[u]:=0;
     34  e:=head[u];
     35  while e<>0 do
     36  begin
     37   v:=vet[e];
     38   if (v<>fa)and(flag[v]=0) then
     39   begin
     40    getroot(v,u);
     41    son[u]:=son[u]+son[v];
     42    f[u]:=max(f[u],son[v]);
     43   end;
     44   e:=next[e];
     45  end;
     46  f[u]:=max(f[u],sum-f[u]);
     47  if f[u]<f[root] then root:=u;
     48 end;
     49 
     50 procedure dfs(u,fa:longint);
     51 var e,v:longint;
     52 begin
     53  inc(top); q[top,1]:=dis[u]; q[top,2]:=u;
     54  e:=head[u];
     55  while e<>0 do
     56  begin
     57   v:=vet[e];
     58   if (v<>fa)and(flag[v]=0) then
     59   begin
     60    dis[v]:=dis[u]*a[v] mod mo;
     61    dfs(v,u);
     62   end;
     63   e:=next[e];
     64  end;
     65 end;
     66 
     67 procedure cmp(x,id:longint);
     68 var y:longint;
     69 begin
     70  x:=exf[x]*k mod mo;
     71  y:=hash[x];
     72  if y=0 then exit;
     73  if y>id then swap(y,id);
     74  if (y<ans1)or((y=ans1)and(id<ans2)) then
     75  begin
     76   ans1:=y; ans2:=id;
     77  end;
     78 end;
     79 
     80 procedure solve(u:longint);
     81 var e,v,i,now:longint;
     82 begin
     83  flag[u]:=1; hash[a[u]]:=u;
     84  e:=head[u];
     85  while e<>0 do
     86  begin
     87   v:=vet[e];
     88   if flag[v]=0 then
     89   begin
     90    top:=0; dis[v]:=a[v];
     91    dfs(v,u);
     92    for i:=1 to top do cmp(q[i,1],q[i,2]); //对于每一个子树,因为不能重复计算u这个根结点,分别计算子树内结果,后面再用加上根结点的答案更新
     93    top:=0; dis[v]:=a[u]*a[v] mod mo;
     94    dfs(v,u);
     95    for i:=1 to top do
     96    begin
     97     now:=hash[q[i,1]];
     98     if (now=0)or(q[i,2]<now) then hash[q[i,1]]:=q[i,2]; //用子树中的路径加上根结点,更新经过根结点的答案
     99    end;
    100   end;
    101   e:=next[e];
    102  end;
    103  hash[a[u]]:=0;
    104  e:=head[u];
    105  while e<>0 do
    106  begin
    107   v:=vet[e];
    108   if flag[v]=0 then
    109   begin
    110    top:=0; dis[v]:=a[u]*a[v] mod mo;
    111    dfs(v,u);
    112    for i:=1 to top do hash[q[i,1]]:=0; //清空所有信息
    113   end;
    114   e:=next[e];
    115  end;
    116  e:=head[u];
    117  while e<>0 do
    118  begin
    119   v:=vet[e];
    120   if flag[v]=0 then
    121   begin
    122    root:=0; sum:=son[v];
    123    getroot(v,0);
    124    solve(root);
    125   end;
    126   e:=next[e];
    127  end;
    128 end;
    129 
    130 begin
    131  assign(input,'hdoj4812.in'); reset(input);
    132  assign(output,'hdoj4812.out'); rewrite(output);
    133  exf[0]:=1; exf[1]:=1;
    134  for i:=2 to 1000003 do exf[i]:=exf[mo mod i]*(mo-mo div i) mod mo;
    135  while not eof do
    136  begin
    137  // fillchar(head,sizeof(head),0);
    138   //fillchar(flag,sizeof(flag),0);
    139   for i:=1 to n do
    140   begin
    141    head[i]:=0; flag[i]:=0;
    142   end;
    143   tot:=0; ans1:=maxlongint; ans2:=maxlongint;
    144   read(n,k);
    145   if n=0 then break;
    146   for i:=1 to n do read(a[i]);
    147   for i:=1 to n-1 do
    148   begin
    149    read(x,y);
    150    add(x,y);
    151    add(y,x);
    152   end;
    153   root:=0; sum:=n; f[0]:=n+1;
    154   getroot(1,0);
    155   solve(root);
    156   if ans1=maxlongint then writeln('No solution')
    157    else writeln(ans1,' ',ans2);
    158  end;
    159  close(input);
    160  close(output);
    161 end.
  • 相关阅读:
    阿里云HBase携X-Pack再进化,重新赋能轻量级大数据平台
    CVE漏洞—PHPCMS2008 /type.php代码注入高危漏洞预警
    傻瓜神经网络入门指南
    一起来看 rxjs
    阿里云ACE共创空间——MQ消息队列产品测试
    阿里毕玄:技术人应如何选择职业发展路线?
    MyBatsi学习
    UEditor学习
    fastJson在java后台转换json格式数据探究(二)--处理数组/List/Map
    JS获取当前年份月
  • 原文地址:https://www.cnblogs.com/myx12345/p/6519725.html
Copyright © 2011-2022 走看看