1. 程式人生 > 其它 >CF1615D X(or)-mas Tree

CF1615D X(or)-mas Tree

CF1615D X(or)-mas Tree

\(Link\)

題意:給定一棵 \(n\) 個點的無根樹,每條邊有邊權。若邊權為 \(-1\) 則邊權暫定。

然後有 \(m\) 條限制條件,每個條件給出形式為 \((u,v,w)\),表示將 \(u\)\(v\) 最短路徑上的邊權異或起來,用二進位制寫出後 \(1\) 的個數的奇偶性

然後構造一種方案,把所有邊權確定下來,要求滿足所有限制。

(碎碎念:賽時沒看到\(1\) 的個數的奇偶性,還以為是憨憨題,然後就GG惹。。。)

\(Solution:\)

首先我們能發現一個性質:

\[popcount(x \oplus y) \equiv popcount(x) \oplus popcount(y)\ (\text{mod}\ 2) \]

挺易證的吧應該。

然後我們欽定 \(1\) 是根。

\(a_i\) 為從 \(1\)\(i\) 的路徑上異或起來的值的 \(popcount\)

於是對於每組 \((u,v,w)\)\(w\) 就等於 \(a_u \oplus a_v\)

然後對於原有的有邊權的邊 \((U,V,W)\),可以看做是另一條限制 \((U,V,popcount(W)\mod 2)\)

現在我們吧這些限制當做一張無向圖的邊,則我們現在要給圖上的每個點 \(i\) 賦一個點權(即 \(a_i\))。滿足對於所有邊 \((u,v,w)\)\(a_u \oplus a_v =w\)

於是我們從 \(1\) 開始(因為 \(a_1\)

一定是 \(0\))dfs 染色,遇到衝突了就是不行。

然後對於每條原來那棵樹上的每條邊 \((u,v)\),如果有邊權就輸出邊權,要麼輸出 \(a_u \oplus a_v\)

\(Code:\)

// Problem: D. X(or)-mas Tree
// Contest: Codeforces Global Round 18
// URL: https://codeforces.com/contest/1615/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Author: jimmyywang
// 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define f(i,a,b) for(ll i=a;i<=b;i++)
#define wt int tt=d;while(tt--)
#define py puts("YES")
#define pn puts("NO")
#define fe(i,e) for(int i=0;i<e.size();i++)
#define vi vector<ll>
inline ll rd() {
	ll x=0,f=1;
	char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c))x=x*10+c-'0',c=getchar();
	return x*f;
}
#define d rd()
#define pb push_back
const ll N=600010;
struct edge{ll v,w,nx;}e[N<<1];
ll hd[N],cnt=1;
void add(ll u,ll v,ll w){e[++cnt]=(edge){v,w,hd[u]};hd[u]=cnt;}
ll qp(ll a,ll b,ll p){
	ll ans=1;while(b){
		if(b&1)ans=ans*a%p;
		a=a*a%p;b>>=1;
	}return ans;
}ll t,n,m;
vector<pair<ll,ll> > ee[200010];
struct node{
	ll x,y,z;
}a[200010];
bool now[200010];
bool vis[200010];
bool flg;
#define mp make_pair
#define pop __builtin_popcount
void dfs(ll u,ll fa,ll p){if(flg)return;
	now[u]=p;vis[u]=1;
	for(int i=hd[u];i;i=e[i].nx){
		ll v=e[i].v;if(v==fa)continue;
		if(vis[v]){
			if((now[v]^now[u])!=e[i].w){flg=1;return;}
			continue;
		}dfs(v,u,p^e[i].w);
	}
}void Dfs(ll u,ll fa){
	fe(i,ee[u]){
		ll v=ee[u][i].first;
		if(v==fa)continue;
		printf("%lld %lld ",u,v);
		if(ee[u][i].second==-1)printf("%lld\n",now[u]^now[v]);
		else printf("%lld\n",ee[u][i].second);
		Dfs(v,u);
	}
}
int main(){
	wt{
		n=d,m=d;
		f(i,1,n)hd[i]=0,ee[i].clear();cnt=1;
		f(i,1,n-1){
			ll u=d,v=d,w=d;
			ee[u].pb(mp(v,w)),ee[v].pb(mp(u,w));
			if(w!=-1)add(u,v,(bool)(pop(w)&1)),add(v,u,(bool)(pop(w)&1));
		}f(i,1,m){
			ll u=d,v=d,w=d;
			add(u,v,w),add(v,u,w);
		}
		f(i,1,n)now[i]=vis[i]=0;flg=0;
		f(i,1,n)if(!vis[i])dfs(i,0,0);
		if(flg){pn;continue;}
		py;Dfs(1,0);
	}
	return 0;
}