题解 CF1615D X(or)-mas Tree
首先根据异或的性质容易发现,若干个数异或的 popcount 是奇是偶等同于每个数 popcount 的奇偶异或起来。因此每条边可以等效于 和 。
我们进行树上差分,对每个点计算一个 表示从根到节点 的路径上的异或和。那么对于每个条件可以转化为 。
对于树上原有的边,也可以进行相同的转化。因此问题变成很经典的题目了。若干 变量若干条件,每个条件是其中两个变量的异或,求一组构造。
你可以使用二分图等方式解决这个问题。我选择的是种类并查集,类似于 [NOI2001] 食物链 的做法。
int fa[N];
vector<int>t[N],v[N];
int find(int x)
{
if (x==fa[x]) return fa[x];
return fa[x]=find(fa[x]);
}
int wq[N];
bool ans;
inline int wr(int z)
{
int res=0;
while (z)
{
if (z&1) res^=1;
z>>=1;
}
return res;
}
void merge(int x,int y)
{
x=find(x),y=find(y);
if (x==y) return;
fa[x]=y;
}
void ddd(int x,int y,int z)
{
if (z==0)
{
if (find(x+n)==find(y)||find(y+n)==find(x))
{
ans=1;
return;
}
merge(x,y),merge(x+n,y+n);
}
else
{
if (find(x)==find(y)||find(y+n)==find(x+n))
{
ans=1;
return;
}
merge(x,y+n),merge(y,x+n);
}
}
void dfs(int x,int f,int vv)
{
if (x==1) a[x]=0,wq[find(1)]=0,wq[find(1+n)]=1;
else
{
if (wq[find(x)]==-1)
{
a[x]=0;
wq[find(x)]=0,wq[find(x+n)]=1;
}
else
{
a[x]=wq[find(x)];
}
if (vv!=-1) printf("%d %d %d\n",x,f,vv);
else printf("%d %d %d\n",x,f,(a[x]^a[f]));
}
for (int i=0;i<t[x].size();i++)
{
if (t[x][i]==f) continue;
dfs(t[x][i],x,v[x][i]);
}
}
void work()
{
n=read(),m=read(),ans=0;
for (int i=1;i<=2*n;i++) fa[i]=i,wq[i]=-1;
for (int i=1;i<=n;i++) t[i].clear();
for (int i=1;i<=n;i++) v[i].clear();
for (int i=1;i<n;i++)
{
int x=read(),y=read(),z=read();
t[x].push_back(y),t[y].push_back(x);
v[x].push_back(z),v[y].push_back(z);
if (z!=-1) ddd(x,y,wr(z));
}
for (int i=1;i<=m;i++)
{
int x=read(),y=read(),z=read();
ddd(x,y,z);
}
if (ans==1)
{
printNO;
return;
}
a[1]=0;
printYES;
dfs(1,-1,-1);
return;
}
int main()
{
int T=read();
while (T--) work();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构