NC227021. 都市的柏油路太硬(T4)
描述
输入描述
输入的第一行包含 N 和 M。
接下来 M 行为三个整数A,B,C,表示 A 到 B 之间有一条长度为 C 的双向泊油路。
接下来一个整数 Q,a1,a2,代表询问总数和随机树生成器的两个参数。注意 a1,a2 可能达到 unsigned long long 类型。关于随机数生成器:
typedef unsigned long long ull; ull myRand(ull &k1, ull &k2){ ull k3 = k1, k4 = k2; k1 = k4; k3 ^= (k3 <<23); k2 = k3 ^ k4 ^ (k3 >>17) ^ (k4 >>26); return k2 + k4; } pair<int,int>myRanq(ull&k1,ull&k2,int MAXN){ int x=myRand(k1,k2)%MAXN+1,y=myRand(k1,k2)%MAXN+1; if(x>y)return make_pair(y,x); else return make_pair(x,y); }调用时传入 myRanq(a1,a2,n),会返回一个 pair<int,int> 类表示询问的两个端点。
输出描述
输出 1 行,表示所有答案的异或和。
示例1
输入:
7 11 2 4 2 1 4 3 7 2 2 3 4 3 5 7 5 7 3 3 6 1 1 6 3 4 2 4 3 5 6 3 7 2 1 10 114 514
输出:
3
说明:
N≤1e5,M≤5e5,Q≤1e7,C≤2e9。提示:由于读入量较大,请选择较快的读入方式。
C++ 解法, 执行用时: 1743ms, 内存消耗: 62268K, 提交时间: 2021-09-11 11:15:56
#include <bits/stdc++.h> #define ull unsigned long long using namespace std; const int N=4e5+10; int dfn[N],st[N][23],dep[N],fa[N],n,m,node,cnt,val[N]; vector<int> g[N]; ull myRand(ull &k1, ull &k2) { ull k3=k1,k4=k2; k1=k4; k3^=(k3<<23); k2=k3^k4^(k3>>17)^(k4>>26); return k2+k4; } pair<int,int>myRanq(ull&k1,ull&k2,int MAXN){ int x=myRand(k1,k2)%n+1,y=myRand(k1,k2)%n+1; if(x>y)return make_pair(y,x); else return make_pair(x,y); } struct Edge { int u,v,w; }e[N*2]; bool cmp(Edge x,Edge y){return x.w<y.w;} int find(int x) { if(x==fa[x]) return x; return fa[x]=find(fa[x]); } void dfs(int p,int depth) { dfn[p]=++cnt;st[cnt][0]=p;dep[p]=depth; for(int i=0;i<g[p].size();i++) { int to=g[p][i]; dfs(to,depth+1); st[++cnt][0]=p; } } void kruskal() { int node=n; for(int i=1;i<=2*n;i++) fa[i]=i; sort(e+1,e+m+1,cmp); for(int i=1;i<=m;i++) { int u=find(e[i].u),v=find(e[i].v); if(u==v) continue; fa[u]=fa[v]=++node;val[node]=e[i].w; g[node].push_back(u);g[node].push_back(v); } dfs(node,0); for(int i=1;(1<<i)<=cnt;i++) for(int j=1;j+(1<<i)-1<=cnt;j++) st[j][i]=dep[st[j][i-1]]<dep[st[j+(1<<i-1)][i-1]]?st[j][i-1]:st[j+(1<<i-1)][i-1]; } int lca(int u,int v) { int l=min(dfn[u],dfn[v]),r=max(dfn[u],dfn[v]),k=log2(r-l+1); return dep[st[l][k]]<dep[st[r-(1<<k)+1][k]]?st[l][k]:st[r-(1<<k)+1][k]; } int main() { scanf("%d %d",&n,&m); for(int i=1;i<=m;i++) scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w); kruskal(); int Q,ans=0;ull a1,a2; scanf("%d %llu %llu",&Q,&a1,&a2); for(int i=1;i<=Q;i++) { pair<int,int> q=myRanq(a1,a2,n); ans^=val[lca(q.first,q.second)]; } printf("%d",ans); }