Luogu P12826 「DLESS-2」XOR and Tree Construction 题解 [ 橙 ] [ 构造 ]
XOR and Tree Construction:险些被诈骗了/ll/ll/ll。
注意到题目给出了自己到自己的路径点权异或和,所以我们可以直接得出每个节点的值,即 \(b_{i,i}\) 的值。
继续考虑如何构造出这棵树,因为我们只需要知道哪些节点之间是直接连边的就可以了,所以只需要得出两个点相邻的条件即可。又注意到有 \(b>0\) 的性质,所以没有任何一个路径异或和为 \(0\),两点间加了任何一段路径都会使路径异或和不等于两点异或和,因此如果 \(b_{i,i}\oplus b_{j,j}=b_{i,j}\),那么两点就是相邻的。将这些相邻点输出即可。
时间复杂度 \(O(tn^2)\)。
#include <bits/stdc++.h>
#define fi first
#define se second
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
#define lc(x) (tr[x].ls)
#define rc(x) (tr[x].rs)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
const int N=505;
int n;
ll b[N][N];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>b[i][j];
if(i==j)cout<<b[i][j]<<" ";
}
}
cout<<'\n';
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
if((b[i][i]^b[j][j])==b[i][j])
cout<<i<<" "<<j<<'\n';
}
int main()
{
//freopen("sample.in","r",stdin);
//freopen("sample.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)solve();
return 0;
}

浙公网安备 33010602011771号