https://codeforces.com/problemset/problem/1174/F
https://codeforces.com/blog/entry/67388
有助于理解树链剖分 和 树分治
题解写得挺好
重链
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <iostream> 8 using namespace std; 9 #define ll long long 10 11 12 const double eps=1e-8; 13 const ll inf=1e9; 14 const ll mod=1e9+7; 15 const int maxn=2e5+10; 16 17 struct node 18 { 19 int d; 20 node *to; 21 }*e[maxn]; 22 23 char str[20]; 24 int siz[maxn],fa[maxn],link[maxn],cnt_link; 25 26 void dfs(int d) 27 { 28 node *p=e[d]; 29 siz[d]=1; 30 while (p) 31 { 32 if (fa[d]!=p->d) 33 { 34 fa[p->d]=d; 35 dfs(p->d); 36 siz[d]+=siz[p->d]; 37 } 38 p=p->to; 39 } 40 } 41 42 void findleaf(int d) 43 { 44 node *p; 45 int num; 46 cnt_link=0; 47 link[0]=d; 48 while (1) 49 { 50 p=e[d]; 51 num=0; 52 while (p) 53 { 54 if (fa[d]!=p->d) 55 { 56 if (siz[p->d]>siz[num]) 57 num=p->d; 58 } 59 p=p->to; 60 } 61 if (!num) 62 break; 63 link[++cnt_link]=num; 64 d=num; 65 } 66 } 67 68 int main() 69 { 70 node *p; 71 int n,x,y,i,root,dist,r,pos; 72 scanf("%d",&n); 73 for (i=1;i<n;i++) 74 { 75 scanf("%d%d",&x,&y); 76 p=new node(); 77 p->d=y; 78 p->to=e[x]; 79 e[x]=p; 80 81 p=new node(); 82 p->d=x; 83 p->to=e[y]; 84 e[y]=p; 85 } 86 gets(str); 87 88 printf("d %d\n",1); 89 fflush(stdout); 90 scanf("%d",&dist); 91 if (dist==0) 92 { 93 printf("! %d\n",1); 94 fflush(stdout); 95 return 0; 96 } 97 98 root=1; 99 while (1) 100 { 101 dfs(root); 102 findleaf(root); 103 104 printf("d %d\n",link[cnt_link]); 105 fflush(stdout); 106 scanf("%d",&r); 107 108 pos=(dist+cnt_link-r)/2; 109 root=link[pos]; 110 dist=dist-pos; 111 if (dist==0) 112 { 113 printf("! %d\n",root); 114 fflush(stdout); 115 return 0; 116 } 117 118 printf("s %d\n",root); 119 fflush(stdout); 120 scanf("%d",&root); 121 dist--; 122 if (dist==0) 123 { 124 printf("! %d\n",root); 125 fflush(stdout); 126 return 0; 127 } 128 } 129 return 0; 130 } 131 /* 132 6 133 1 2 134 2 3 135 3 4 136 4 5 137 5 6 138 139 7 140 1 2 141 1 3 142 2 4 143 2 5 144 3 6 145 3 7 146 147 148 149 7 150 1 2 151 1 3 152 2 4 153 2 5 154 3 6 155 3 7 156 d 1 157 2 158 d 7 159 4 160 s 1 161 2 162 d 7 163 */
树重心
为了省去vis初始化
way1:
use father vex
way2:
vis[d]=1;
...
vis[d]=0;
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <iostream> 8 using namespace std; 9 #define ll long long 10 11 12 const double eps=1e-8; 13 const ll inf=1e9; 14 const ll mod=1e9+7; 15 const int maxn=2e5+10; 16 17 struct node 18 { 19 int d; 20 node *to; 21 }*e[maxn]; 22 23 char str[20]; 24 int siz[maxn],fa[maxn],link[maxn],cnt_link; 25 26 void dfs(int d) 27 { 28 node *p=e[d]; 29 siz[d]=1; 30 while (p) 31 { 32 if (fa[d]!=p->d) 33 { 34 fa[p->d]=d; 35 dfs(p->d); 36 siz[d]+=siz[p->d]; 37 } 38 p=p->to; 39 } 40 } 41 42 void findleaf(int d) 43 { 44 node *p; 45 int num; 46 cnt_link=0; 47 link[0]=d; 48 while (1) 49 { 50 p=e[d]; 51 num=0; 52 while (p) 53 { 54 if (fa[d]!=p->d) 55 { 56 if (siz[p->d]>siz[num]) 57 num=p->d; 58 } 59 p=p->to; 60 } 61 if (!num) 62 break; 63 link[++cnt_link]=num; 64 d=num; 65 } 66 } 67 68 int main() 69 { 70 node *p; 71 int n,x,y,i,root,dist,r,pos; 72 scanf("%d",&n); 73 for (i=1;i<n;i++) 74 { 75 scanf("%d%d",&x,&y); 76 p=new node(); 77 p->d=y; 78 p->to=e[x]; 79 e[x]=p; 80 81 p=new node(); 82 p->d=x; 83 p->to=e[y]; 84 e[y]=p; 85 } 86 gets(str); 87 88 printf("d %d\n",1); 89 fflush(stdout); 90 scanf("%d",&dist); 91 if (dist==0) 92 { 93 printf("! %d\n",1); 94 fflush(stdout); 95 return 0; 96 } 97 98 root=1; 99 while (1) 100 { 101 fa[root]=0; 102 dfs(root); 103 findleaf(root); 104 105 printf("d %d\n",link[cnt_link]); 106 fflush(stdout); 107 scanf("%d",&r); 108 if (r==0) 109 { 110 printf("! %d\n",link[cnt_link]); 111 fflush(stdout); 112 return 0; 113 } 114 115 pos=(dist+cnt_link-r)/2; 116 root=link[pos]; 117 dist=dist-pos; 118 if (dist==0) 119 { 120 printf("! %d\n",root); 121 fflush(stdout); 122 return 0; 123 } 124 125 printf("s %d\n",root); 126 fflush(stdout); 127 scanf("%d",&root); 128 dist--; 129 if (dist==0) 130 { 131 printf("! %d\n",root); 132 fflush(stdout); 133 return 0; 134 } 135 } 136 return 0; 137 } 138 /* 139 6 140 1 2 141 2 3 142 3 4 143 4 5 144 5 6 145 146 */
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <iostream> 8 using namespace std; 9 #define ll long long 10 11 12 const double eps=1e-8; 13 const ll inf=1e9; 14 const ll mod=1e9+7; 15 const int maxn=2e5+10; 16 17 struct node 18 { 19 int d; 20 node *to; 21 }*e[maxn]; 22 23 char str[20]; 24 int siz[maxn],fa[maxn],link[maxn],cnt_link; 25 bool vis[maxn]; 26 27 void dfs(int d) 28 { 29 node *p=e[d]; 30 vis[d]=1; 31 siz[d]=1; 32 while (p) 33 { 34 if (!vis[p->d]) 35 { 36 dfs(p->d); 37 siz[d]+=siz[p->d]; 38 fa[p->d]=d; 39 } 40 p=p->to; 41 } 42 vis[d]=0; 43 } 44 45 void findleaf(int d) 46 { 47 node *p; 48 int num; 49 cnt_link=0; 50 link[0]=d; 51 while (1) 52 { 53 p=e[d]; 54 num=0; 55 while (p) 56 { 57 if (fa[d]!=p->d) 58 { 59 if (siz[p->d]>siz[num]) 60 num=p->d; 61 } 62 p=p->to; 63 } 64 if (!num) 65 break; 66 link[++cnt_link]=num; 67 d=num; 68 } 69 } 70 71 int main() 72 { 73 node *p; 74 int n,x,y,i,root,dist,r,pos; 75 scanf("%d",&n); 76 for (i=1;i<n;i++) 77 { 78 scanf("%d%d",&x,&y); 79 p=new node(); 80 p->d=y; 81 p->to=e[x]; 82 e[x]=p; 83 84 p=new node(); 85 p->d=x; 86 p->to=e[y]; 87 e[y]=p; 88 } 89 gets(str); 90 91 printf("d %d\n",1); 92 fflush(stdout); 93 scanf("%d",&dist); 94 if (dist==0) 95 { 96 printf("! %d\n",1); 97 fflush(stdout); 98 return 0; 99 } 100 101 root=1; 102 while (1) 103 { 104 // memset(vis,0,sizeof(vis)); 105 fa[root]=0; 106 dfs(root); 107 findleaf(root); 108 109 printf("d %d\n",link[cnt_link]); 110 fflush(stdout); 111 scanf("%d",&r); 112 if (r==0) 113 { 114 printf("! %d\n",link[cnt_link]); 115 fflush(stdout); 116 return 0; 117 } 118 119 pos=(dist+cnt_link-r)/2; 120 root=link[pos]; 121 dist=dist-pos; 122 if (dist==0) 123 { 124 printf("! %d\n",root); 125 fflush(stdout); 126 return 0; 127 } 128 129 printf("s %d\n",root); 130 fflush(stdout); 131 scanf("%d",&root); 132 dist--; 133 if (dist==0) 134 { 135 printf("! %d\n",root); 136 fflush(stdout); 137 return 0; 138 } 139 } 140 return 0; 141 } 142 /* 143 6 144 1 2 145 2 3 146 3 4 147 4 5 148 5 6 149 150 */