CF1615D X(or)-mas Tree
阿新 • • 發佈:2021-12-25
CF1615D X(or)-mas Tree
一定是 \(0\))dfs 染色,遇到衝突了就是不行。
\(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\)
然後對於每條原來那棵樹上的每條邊 \((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; }