码迷,mamicode.com
首页 > 其他好文 > 详细

hdu4812 D Tree

时间:2015-08-21 00:00:47      阅读:473      评论:0      收藏:0      [点我收藏+]

标签:

树上的点分治。

首先为了避免超时预处理逆元,对于x(<mod),我们希望找到f-1(x) = y 满足y * x % mod = k。

由存在a, b : x *a + y * b = gcd(x, y), mod 为素数,故有 x * a + mod * b = 1。

由EXTENDED-EUCLID找出a (< mod)。

对于树上的分治,首先找出当前树的重心,处理剔除重心后的各个子树,合法链属于其中一个子树或者经过树根。

 

acm.hdu.edu.cn/showproblem.php?pid=4812

 

技术分享
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #pragma comment(linker,"/STACK:102400000,102400000")
  5 
  6 using namespace std;
  7 typedef __int64 LL;
  8 const int inf = 0x3f3f3f3f;
  9 const int maxn = 1e5 + 10;
 10 const int mod = 1e6 + 3;
 11 
 12 struct Edge{
 13     int to, next;
 14 }edge[maxn * 2];
 15 int head[maxn], f[mod], belong[mod], g[mod];
 16 bool vis[maxn];
 17 int n, N, root;
 18 LL K, val[maxn], path[maxn];
 19 int cnt1, mini;
 20 LL d, x, y;
 21 int ans[2], sum[maxn], id[maxn];
 22 
 23 void addEdge(int u, int v){
 24     edge[N].next = head[u];
 25     edge[N].to = v;
 26     head[u] = N++;
 27 }
 28 
 29 void eEuclid(LL a, LL b){
 30     if(!b){
 31         d = a; x = 1; y = 0;
 32         return;
 33     }
 34     eEuclid(b, a % b);
 35     LL x1 = x;
 36     x = y;
 37     y = x1 - a / b * y;
 38 }
 39 
 40 void init(){
 41     //calculate inverse element
 42     for(int i = 0; i < mod; i++){
 43         eEuclid(mod, i);
 44         while(y < 0) y += mod;
 45         g[i] = y % mod;
 46     }
 47 }
 48 
 49 void getRoot(int u){
 50     sum[u] = 1;
 51     int maxii = 0;
 52     vis[u] = 1;
 53     for(int i = head[u]; i + 1; i = edge[i].next){
 54         int v = edge[i].to;
 55         if(vis[v]) continue;
 56         getRoot(v);
 57         sum[u] += sum[v];
 58         maxii = max(sum[v], maxii);
 59     }
 60     vis[u] = 0;
 61     maxii = max(maxii, sum[0] - sum[u]);
 62     if(maxii < mini) mini = maxii, root = u;
 63 }
 64 
 65 void update(int a, int b){
 66     if(a > b) swap(a, b);
 67     if(ans[0] == -1 || ans[0] > a){
 68         ans[0] = a, ans[1] = b;
 69         return;
 70     }
 71     if(ans[0] == a && ans[1] > b) ans[1] = b;
 72 }
 73 
 74 void dfs(int u, LL num){
 75     path[cnt1] = num * val[u] % mod;
 76     id[cnt1++] = u;
 77     LL tem = path[cnt1 - 1];
 78     vis[u] = 1;
 79     for(int i = head[u]; i + 1; i = edge[i].next){
 80         int v = edge[i].to;
 81         if(vis[v]) continue;
 82         dfs(v, tem);
 83     }
 84     vis[u] = 0;
 85 }
 86 
 87 void solve(int u, int cnt){
 88     if(cnt == 1) return;
 89     sum[0] = cnt;
 90     mini = inf;
 91     getRoot(u);
 92     vis[root] = 1;
 93     for(int i = head[root]; i + 1; i = edge[i].next){
 94         int v = edge[i].to;
 95         if(vis[v]) continue;
 96         cnt1 = 0;
 97         dfs(v, 1);
 98         for(int j = 0; j < cnt1; j++){
 99             if(path[j] * val[root] % mod == K) update(id[j], root);
100             LL tem = K * g[path[j] * val[root] % mod] % mod;
101             if(belong[tem] != N) continue;
102             update(id[j], f[tem]);
103         }
104         for(int j = 0; j < cnt1; j++){
105             int tem = path[j];
106             if(belong[tem] != N || f[tem] > id[j]) f[tem] = id[j], belong[tem] = N;
107         }
108     }
109     N++;
110     for(int i = head[root]; i + 1; i = edge[i].next){
111         int v = edge[i].to;
112         if(vis[v]) continue;
113         solve(v, sum[v]);
114     }
115 }
116 
117 int main(){
118     init();
119     while(~scanf("%d%I64d", &n, &K)){
120         for(int i = 1; i <= n; i++) scanf("%I64d", &val[i]);
121         memset(head, -1, sizeof head);
122         memset(belong, -1, sizeof belong);
123         memset(ans, -1, sizeof ans);
124         memset(vis, 0, sizeof vis);
125         N = 0;
126         for(int i = 1, p, q; i < n; i++){
127             scanf("%d%d", &p, &q);
128             addEdge(p, q);
129             addEdge(q, p);
130         }
131         N = 0;
132         solve(1, n);
133         if(ans[0] == -1) puts("No solution");
134         else printf("%d %d\n", ans[0], ans[1]);
135     }
136     return 0;
137 }
View Code

 

hdu4812 D Tree

标签:

原文地址:http://www.cnblogs.com/astoninfer/p/4746387.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!