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;
}
posted @ 2025-06-15 00:04  KS_Fszha  阅读(19)  评论(0)    收藏  举报