P8965 坠梦 | Falling into Dream 题解
0x00 \mathcal{O}(n^3) 预处理 \mathcal{O}(n) 查询
这种大量查询的题目很容易想到的是预处理出来每一对
0x01 \mathcal{O}(n^2) 预处理 \mathcal{O}(n) 查询
对于 0x00 部分的算法,可以进行优化,首先预处理把每一个对
对于
0x02 \mathcal{O}(n) 预处理 \mathcal{O}(1) 查询
刚才的算法打开了一个很好的思路就是利用了异或的自反性,希望还可以利用更多这样的性质,这时整体考虑
可以发现
#include <cstdio>
#include <algorithm>
#include <queue>
#define _min(a,b) ((a)<(b)?(a):(b))
#define _max(a,b) ((a)>(b)?(a):(b))
struct edge{
int to,nxt,w;
edge(){
nxt=-1;
return;
}
}tree[1000010<<1];
int tot,head[1000010];
long long V_pre[1000010];
void addEdge(int u,int v,int w){
tree[tot].nxt=head[u];
tree[tot].w=w;
tree[tot].to=v;
head[u]=tot;
++tot;
return;
}
int read(){
long long x=0;char f=0,c=getchar();
while(c<'0'||'9'<c) f|=(c=='-'),c=getchar();
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c&15),c=getchar();
return f?-x:x;
}
void dfs(int u,int p,int w){
V_pre[u]=V_pre[p]^w;
for(int i=head[u];~i;i=tree[i].nxt){
if(tree[i].to!=p)
dfs(tree[i].to,u,tree[i].w);
}
}
int main(){
register int i,u,v,w,x,y,l,r;
register long long ans;
int n=read();
int Q=read();
for(i=1;i<=n;++i) head[i]=-1;
for(i=1;i<n;++i){
u=read();
v=read();
w=read();
addEdge(u,v,w);
addEdge(v,u,w);
}
dfs(1,1,0);
for(i=0;i<Q;++i){
x=read();
y=read();
l=read();
r=read();
ans=(((r-l+1)&1)?(V_pre[x]^V_pre[y]):0);
printf("%lld",ans);
putchar('\n');
}
return 0;
}