T1
题目
官方题解
考虑暴力,发现奇数边包赢,偶数边如果异或和为\(0\)则输,当然也有特例,比如\(2->4->8->14->\),这\(4\)条边异或为\(0\)但其实必赢,
所以,为了避免这种情况发生,我们使用\(hash\)
XORHashing
这样与处理出\(dis\),两点\(u,v\)即为\(dis_u xor dis_v\)
暴力的话\(O(n^2)\)
点击查看代码
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define lid (rt<<1)
#define rid (rt<<1|1)
// #define endl '\n'
#define pii pair<int,int>
#define ull unsigned long long
#define pb push_back
#define ts cout<<"----------------"<<endl;
#define bs bitset<65>
using namespace std;
const int N = 5e5+5;
const ull B=233;
ull qpow(ull a,ull b)
{ull ans=1;while(b){if(b&1)ans=ans*a;a=a*a;b>>=1;}return ans;
}
int n,dep[N];ull dis[N];int f[N][24];
vector <pii> edge[N];
map <int,int> mp;
void dfs(int u,int fa)
{dep[u]=dep[fa]+1;// cout<<u<<endl;// f[u][0]=fa;// for(int i=1;i<=20;i++)// f[u][i]=f[f[u][i-1]][i-1];for(auto [to,w]:edge[u]){if(to==fa)continue;dis[to]=dis[u]^w;dfs(to,u);// mp[dis[to]]++;}
}
int lca(int x,int y)
{if(dep[x]>dep[y])swap(x,y);for(int i=20;i>=0;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i];if(x==y)return 0;for(int i=20;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];return f[x][0];
}
ll C(ll n)
{return 1ll*n*(n-1)/2ll;
}
int get(int u,int v)
{return dep[u]+dep[v]-2*dep[lca(u,v)];
}
int main()
{speed();// freopen("T1.in","r",stdin);// freopen("in.in","r",stdin);// freopen("out.out","w",stdout);int T;cin>>T;while(T--){cin>>n;int u,v;ull w;// while(q.size())q.pop();for(int i=1;i<=n;i++)edge[i].clear();for(int i=1;i<=n-1;i++){cin>>u>>v>>w;// cout<<u<<" "<<v<<" "<<w<<endl;w=qpow(B,w);edge[u].pb({v,w});edge[v].pb({u,w});}ll ans=C(n);dfs(1,0);for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){if(dis[i]^dis[j])continue;// if(get(i,j)%2)continue;// cout<<i<<" "<<j<<endl;ans--;} }cout<<ans<<endl;}return 0;
}
/*
hack
1
5
1 2 2
2 3 4
3 4 8
4 5 14
*/
正解,其实很好想,开个桶记录一下\(dis\)最后统计答案即可,注意相同内部两两组合
点击查看代码
#include <bits/stdc++.h>
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define lid (rt<<1)
#define rid (rt<<1|1)
// #define endl '\n'
#define pii pair<int,ull>
#define ull unsigned long long
#define pb push_back
#define ts cout<<"----------------"<<endl;
#define bs bitset<65>
using namespace std;
const int N = 5e5+5;
const ull B=233;
ull qpow(ull a,ull b)
{ull ans=1;while(b){if(b&1)ans=ans*a;a=a*a;b>>=1;}return ans;
}
int n,dep[N],un,tong[N];ull dis[N];int f[N][24];
vector <pii> edge[N];
map <ull,int> mp;
void dfs(int u,int fa)
{dep[u]=dep[fa]+1;for(auto [to,w]:edge[u]){if(to==fa)continue;dis[to]=dis[u]^w;// cout<<dis[to]<<endl;mp[dis[to]]++;dfs(to,u);// mp[dis[to]]++;}
}
ll C(ll n)
{return 1ll*n*(n-1)/2ll;
}
int main()
{speed();// freopen("T1.in","r",stdin);// freopen("in.in","r",stdin);// freopen("out.out","w",stdout);int T;cin>>T;while(T--){cin>>n;int u,v;ull w;mp.clear();// while(q.size())q.pop();for(int i=1;i<=n;i++)edge[i].clear(),dis[i]=0;for(int i=1;i<=n-1;i++){cin>>u>>v>>w;// cout<<u<<" "<<v<<" "<<w<<endl;w=qpow(B,w);edge[u].pb({v,w});edge[v].pb({u,w});}ll ans=C(n);dfs(1,0);mp[0]++;for(int i=1;i<=n;i++){if(mp[dis[i]]>1){// cout<<mp[dis[i]]<<endl;ans-=C(mp[dis[i]]);mp[dis[i]]=0;}}cout<<ans<<endl;}return 0;
}
/*
hack
1
5
1 2 2
2 3 4
3 4 8
4 5 14
*/