以下是使用线段树的代码,全测试点RE,但只将addline和dfs两个int函数改成void就AC了。想问下这是什么原理……
ps1:即从int addline(int x, int y) 改为 void addline(int x, int y)
ps2:是否开O2似乎结果一样……而只改dfs函数的时候会134会RE其他TLE,而只改addline函数则全RE
#include <cstdio>
#include <cstring>
#include <stack>
#define DEBUG
#define ll long long
#define MAX 540000
#define swp(x, y) int temp = x; x = y; y = temp
#define rep(i, init, n) for(int i = init; i < n; i++)
#define lowbit(i) ((i)&-(i))
using namespace std;
int nums[MAX*8];
int cnt = 0;
int pos = 1;
int next[MAX*2], to[MAX*2], head[MAX];
int lg[MAX];
int depth[MAX];
int last[MAX];
int query(int x, int y){
if(x > y){
swp(x, y);
}
int tmin = nums[x];
if(depth[nums[x]] > depth[nums[y]]){
tmin = nums[y];
}
while((x >> 1)!=(y >> 1)){
if((x & 1) == 0){
if(nums[x+1] != -1 && depth[tmin] > depth[nums[x+1]]){
tmin = nums[x+1];
}
}
if((y & 1) == 1){
if(nums[y-1] != -1 && depth[tmin] > depth[nums[y-1]]){
tmin = nums[y-1];
}
}
x >>= 1;
y >>= 1;
}
return tmin;
}
int addline(int x, int y){
cnt++;
next[cnt] = head[x];
to[cnt] = y;
head[x] = cnt;
}
int dfs(int i, int fa){
depth[i] = depth[fa]+1;
nums[pos] = i;
last[i] = pos;
pos++;
for(int p = head[i]; p != 0; p = next[p]){
if(to[p] == fa){
continue;
}
dfs(to[p], i);
}
if(fa != 0){
nums[pos] = fa;
last[fa] = pos;
pos++;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("1.txt", "r", stdin);
#endif
int n, m, s;
scanf("%d %d %d", &n, &m, &s);
memset(head, 0, sizeof(head));
memset(nums, -1, sizeof(nums));
rep(i, 0, n-1){
int x, y;
scanf("%d %d", &x, &y);
addline(x, y);
addline(y, x);
}
depth[0] = 0;
for(; pos < 2*n; pos <<= 1){
;
}
int ppos = pos >> 1;
dfs(s, 0);
for(; ppos > 0; ppos >>= 1){
for(int i = ppos; nums[i<<1] != -1 && (i < (ppos << 1)); i++){
nums[i] = nums[i<<1];
if(nums[(i<<1)+1] != -1 && depth[nums[i<<1]] > depth[nums[(i<<1)+1]]){
nums[i] = nums[(i<<1)+1];
}
}
}
rep(i, 0, m){
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", query(last[x], last[y]));
}
return 0;
}