一个类似2-SAT的思想,但是简化了很多。只需要用到并查集实现。

题目描述

企鹅国打算种一批树。所谓树,就是由$N$个结点与$N-1$条边连接而成的连通无向图。企鹅国的国王对于这些树有下列要求:

1. 树没有指定根,但它的形态是给定的(即这$N-1$条边是给出的);
2. 树的每条边上可以放置一朵花(当然也可以不放置)
3. 共$Q$条约束,第$i$组约束规定:标号$u[i]$的结点到标号$v[i]$的结点的简单路径上,花的数量为奇数或偶数。

现在,国王想事先知道他最多能种多少棵不一样的树(两棵树被视为不一样当且仅一棵树中某条边的放花情况与另一棵树不相同)。

输入输出格式

输入格式:

第$1$行两个整数$N,Q$;

接下来$N-1$行,每行两个整数$u,v$,表示$latex u,v$间存在一条边;

接下来$Q$行,每三个整数$u[i],v[i],k[i]$,若$k[i]$为$0$,表示$u[i]$到$v[i]$的简单路径的上花的个数为偶数, 否则为奇数。

输出格式:

一行一个整数,表示能种的不一样的树的种树,对$998244353$取模。

输入输出样例

输入样例#1:

5 3
1 2
1 3
2 4
2 5
1 4 0
1 5 1
1 3 0

输出样例#1:

2

说明

$20\%$的数据:$N, Q\le 20$;

$40\%$的数据:$N, Q\le 100$;

$70\%$的数据:$N, Q\le 5000$;

$100\%$的数据:$N, Q\le 100000, 0\le k[i]\le 1$。

题解:

    这里两点之间的路径为奇数还是偶数与树上唯一一条路径有关,如下图,为了简化问题,我们把奇数和偶数定义为异或和为1和0。

    两点间唯一路径就是这条黄色的路径。我们发现,要保证这条路径的异或和等于给定值,那么它们分别到根的异或和的异或值也是等于给定值的,因为$x\mathrm{xor} x=0$。因此要满足$x$到$y$这条路径的异或和等于给定值,那么只要满足两个点到根的异或和相异或等于给定值就可以了,也就相当于把上面重合的地方消掉了。

    问题转化为异或,我们就不用关心树上的关系了也就是说这棵树废掉了。只需要给每个点一个到根的异或和(0/1)就可以了。

    那么根据给出的询问信息,我们需要知道哪些点必须和哪些点到根的异或和相同,哪些点和哪些点相反。我们要把每个点拆成两个部分,一部分关联相同,另一部分关联的可以不同。样例构造出来就是这样:

    那么一个连通块就代表了同一种到根的异或和,一对连通块(可以发现连通块总是对称的)代表了一对相反的到根的异或和。而每个节点真正到根的异或和是不带'的节点所在的连通块。因此我们只需要保证每个连通块取相同的值,每对连通块取对应的值就可以了。而每对连通块都有两种取值选择,如果相反,就是01/10,如果相同,就是00/11。那么我们一共有2连通块对数种选择。不过有一点要注意,1到根的异或和一定是0,所以有一组是不能任选的。所以我们有2连通块对数-1种选择。

    判断连通块个数,用并查集就好了。

Code:

#include<cstdio>
#include<cstring>
int s[200100];
int my_find(int x)
{
if(s[x]==x)
return x;
return s[x]=my_find(s[x]);
}
void my_union(int x,int y)
{
s[my_find(y)]=my_find(x);
}
bool app[200100];
int qpow(int x,int y)
{
long long ans=1,m=x;
while(y)
{
if(y&1)
ans*=m;
ans%=998244353;
m*=m;
m%=998244353;
y>>=1;
}
return ans;
}
int main()
{
int n,q;
int u,v,w;
scanf("%d%d",&n,&q);
for(int i=1;i<n;++i)
{
s[i]=i;
scanf("%d%d",&u,&v);//可以直接过滤掉
}
for(int i=n;i<=2*n;++i)
s[i]=i;
for(int i=1;i<=q;++i)
{
scanf("%d%d%d",&u,&v,&w);
if(!w)
{
my_union(u,v);//上面图片连边的过程
my_union(u+n,v+n);
}
else
{
my_union(u,v+n);
my_union(u+n,v);
}
}
int cnt=0;
for(int i=1;i<=2*n;++i)
if(!app[my_find(i)])
{
app[my_find(i)]=1;
++cnt;
}
printf("%d\n",qpow(2,cnt-1>>1));//因为所有都统计了,所以要减1除以2
return 0;
}

【2-SAT】【并查集】NOIp模拟题 植树方案 题解的更多相关文章

  1. [Noip模拟题]统计方案​

    题目并不难,想一下就会了,我真的智商持续下降,取模情况下做除法我都没想到逆元. 总之想到逆元就好写了,还是\(meet\ in\ the\ middle\)裸题,数组开不下用\(hash/map\)存 ...

  2. 【BZOJ1998】[HNOI2010]物品调度(并查集,模拟)

    [BZOJ1998][HNOI2010]物品调度(并查集,模拟) 题面 BZOJ,为啥这题都是权限题啊? 洛谷 题解 先不管\(0\)位置是个空,把它也看成一个箱子.那么最终的答案显然和置换循环节的个 ...

  3. poj 2236:Wireless Network(并查集,提高题)

    Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 16065   Accepted: 677 ...

  4. poj 2524:Ubiquitous Religions(并查集,入门题)

    Ubiquitous Religions Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 23997   Accepted:  ...

  5. poj 1611:The Suspects(并查集,经典题)

    The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 21472   Accepted: 10393 De ...

  6. hrbustoj 1073:病毒(并查集,入门题)

    病毒Time Limit: 1000 MS Memory Limit: 65536 KTotal Submit: 719(185 users) Total Accepted: 247(163 user ...

  7. 【入门OJ】2003: [Noip模拟题]寻找羔羊

    这里可以复制样例: 样例输入: agnusbgnus 样例输出: 6 这里是链接:[入门OJ]2003: [Noip模拟题]寻找羔羊 这里是题解: 题目是求子串个数,且要求简单去重. 对于一个例子(a ...

  8. NOIP模拟题汇总(加厚版)

    \(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...

  9. 9.9 NOIP模拟题

    9.9 NOIP模拟题 T1 两个圆的面积求并 /* 计算圆的面积并 多个圆要用辛普森积分解决 这里只有两个,模拟计算就好 两圆相交时,面积并等于中间两个扇形面积减去两个三角形面积 余弦定理求角度,算 ...

随机推荐

  1. UOJ 176 新年的繁荣

    挺妙的解法. 发现边权很小,我们可以考虑从大到小枚举边权来进行$kruskal$算法,这样子对于每一个边权$i$,我们只要枚举$0 \leq j < m$,找到一个点使它的点权为$i | 2^j ...

  2. osm2pgsql导入duplicate key error in slim mode

    This is a well known issue and one that is likely not going to be addressed any time soon. While the ...

  3. pip指定安装包版本

    pip是目前最好用的python包关系工具,没有之一. 1.版本范围符号:==.>=.<=.>.<. 2.单个安装示例: 1 2 3 pip install cchardet  ...

  4. c# 获取非托管指针长度

    public List<string> GetPDFValues() { List<string> strs = new List<string>(); unsaf ...

  5. 1.ef 映射关系

    1.edmx <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="3 ...

  6. 如何确定tabcontrol哪一页码是活跃页???

    tabControl1.SelectedIndex属性 显示了现在显示的是哪一页码内的控件.

  7. 开源IMS平台中间件Mobicents

    下面内容来自百度百科 Mobicents 是一个高伸缩性.事件驱动的应用服务器.是一款专业的.开放源代码的 VoIP 中间件平台.Mobicents是首个采用JAIN SLEE标准的开放式源代码电信应 ...

  8. JS和JQuery的比较

    一. Jquery它是javascript的一个轻量级框架,是对javascript进行封装. 二.JQuery和JS都有加载函数,但表达方式不同. 1.JS中的加载函数: //整个文档加载完毕后执行 ...

  9. 构建空Datatable

    方法一 DT = new DataTable(); DataRow DR = DT.NewRow(); //构建列(名称,数据类型) DT.Columns.Add("代码", Ty ...

  10. raiden_graph

    使用mermaid描述 raiden 通道 AB,正常状态 graph LR A-- 60,100,S_100 ---B 通道 AB closed graph LR A((A)) -. 60,100 ...