spoj 913 Query on a tree II 倍增

 题意:给定一棵边带权树

定义两种询问

DIST a b : a b之间距离

KTH a b k : a b之间的路径的第k个数

  1 #include<iostream>
2 #include<cstring>
3 #include<cmath>
4 #include<cstdio>
5 using namespace std;
6 #define MAXN 10010
7 struct node
8 {
9 int num,weight;
10 node *next;
11 };
12 node *graph[MAXN];
13 node memo[2*MAXN];
14 int euler[2*MAXN],father[MAXN][20],d[MAXN],home[MAXN],Log[2*MAXN],length[MAXN];
15 int sparse_table[2*MAXN][20],sparse_table_num[2*MAXN][20];
16 int n,top;
17 void my_log()
18 {
19 Log[1]=0;
20 for(int i=2;i<2*MAXN;i++)
21 Log[i]=Log[i/2]+1;
22 }
23 void add(int x,int y,int z)
24 {
25 node *p=&memo[top++];
26 p->num=y; p->weight=z; p->next=graph[x]; graph[x]=p;
27 p=&memo[top++];
28 p->num=x; p->weight=z; p->next=graph[y]; graph[y]=p;
29 }
30 void dfs(int i,int deep,int fa,int w)
31 {
32 euler[++top]=i; home[i]=top;
33 d[i]=deep; father[i][0]=fa; length[i]=length[fa]+w;
34 for(int j=1;(1<<j)<d[i];j++)
35 {
36 father[i][j]=father[father[i][j-1]][j-1];
37 }
38 for(node *p=graph[i];p;p=p->next)
39 if(p->num!=father[i][0])
40 {
41 dfs(p->num,deep+1,i,p->weight);
42 euler[++top]=i;
43 }
44 }
45 void build_sparse_table()
46 {
47 int i,j;
48 for(i=1;i<=top;i++)
49 {
50 sparse_table[i][0]=d[euler[i]];
51 sparse_table_num[i][0]=euler[i];
52 }
53 for(j=1;(1<<j)<=top;j++)
54 {
55 for(i=1;i<=top-(1<<j)+1;i++)
56 {
57 if(sparse_table[i][j-1]<sparse_table[i+(1<<(j-1))][j-1])
58 {
59 sparse_table[i][j]=sparse_table[i][j-1];
60 sparse_table_num[i][j]=sparse_table_num[i][j-1];
61 }
62 else
63 {
64 sparse_table[i][j]=sparse_table[i+(1<<(j-1))][j-1];
65 sparse_table_num[i][j]=sparse_table_num[i+(1<<(j-1))][j-1];
66 }
67 }
68 }
69 }
70 int LCA(int x,int y)
71 {
72 if(x>y)
73 {
74 int t;
75 t=x; x=y; y=t;
76 }
77 int z=Log[y-x+1];
78 if(sparse_table[x][z]<sparse_table[y-(1<<z)+1][z])
79 return sparse_table_num[x][z];
80 else return sparse_table_num[y-(1<<z)+1][z];
81 }
82 int find(int x,int l)
83 {
84 int i=0;
85 while(l>0)
86 {
87 if(l&1) x=father[x][i];
88 i++;
89 l>>=1;
90 }
91 return x;
92 }
93
94 void solve()
95 {
96 char c[10];
97 int x,y,z;
98 int temp;
99 while(1)
100 {
101 scanf("%s",c);
102 if(c[0]=='D'&&c[1]=='O') break;
103 if(c[0]=='D')
104 {
105 scanf("%d%d",&x,&y);
106 temp=length[x]+length[y]-2*length[LCA(home[x],home[y])];
107 printf("%d\n",temp);
108 }
109 else
110 {
111 scanf("%d%d%d",&x,&y,&z);
112 int fa=LCA(home[x],home[y]);
113 if(d[x]-d[fa]==z-1)
114 {
115 printf("%d\n",fa);
116 }
117 else if(d[x]-d[fa]>z-1)
118 {
119 printf("%d\n",find(x,z-1));
120 }
121 else printf("%d\n",find(y,d[x]+d[y]-2*d[fa]-z+1));
122 }
123 }
124 printf("\n");
125 }
126
127
128
129
130 int main()
131 {
132 int T,i;
133 int x,y,z;
134 my_log();
135 scanf("%d",&T);
136 while(T--)
137 {
138 top=0;
139 memset(graph,0,sizeof(graph));
140 memset(father,0xff,sizeof(father));
141 memset(length,0,sizeof(length));
142 scanf("%d",&n);
143 for(i=1;i<n;i++)
144 {
145 scanf("%d%d%d",&x,&y,&z);
146 add(x,y,z);
147 }
148 top=0;
149 length[1]=0;
150 dfs(1,1,0,0);
151 /*for(i=1;i<=n;i++)
152 for(int j=0;j<=2;j++)
153 {
154 printf("%d %d %d %d\n",i,j,father[i][j],d[father[i][j]]);
155 }*/
156 build_sparse_table();
157 solve();
158 }
159 return 0;
160 }



原文地址:https://www.cnblogs.com/myoi/p/2378990.html