[atAGC052F]Tree Vertices XOR
结论
注意到如果$x$周围有偶数个1,对$x$操作显然不会改变$a_{x}$,因此不妨强制操作的点周围要有奇数个1,不难发现此时恰好会改变该点,即令$a_{x}=a_{x}\oplus 1$
称$\{a_{i}\}$合法当且仅当其能被得到,问题即统计合法序列数
显然操作是可逆的,因此$\{a_{i}\}$合法等价于其能通过操作使得$\forall 1\le i\le n,a_{i}=1$
结论1:若$\{a_{i}\}$能通过操作得到$\{b_{i}\}$,两者合法性相同
根据操作的可逆性显然成立
称$\{a_{i}\}$的"1子图"为所有所有满足$a_{i}=1$的点的导出子图,考虑以下结论——
结论2:操作不会改变1子图连通块数的奇偶性
不妨假设操作$x$,并记与$x$相邻的点中有$s$个1,则有$s\equiv 1(mod\ 2)$
对$a_{x}$的变化分类讨论,不难得到连通块数即$\pm (s-1)$,而$s-1$为偶数,也即不会改变奇偶性
另一方面,注意到最终$\forall 1\le i\le n,a_{i}=1$时1子图的连通块数为1,因此不难得到$\{a_{i}\}$合法的(一个)必要条件为$\{a_{i}\}$的1子图连通块数为奇数
另外,$\{a_{i}\}$合法的另一个必要条件即存在一个点可以操作(周围有奇数个点为1)
(特别的,在$\forall 1\le i\le n,a_{i}=1$时,由于$n\ge 3$,总存在叶子,该点即满足条件)
事实上,若原树存在一个点满足其度数$\ge 3$且将其删除后存在两个连通块点数$\ge 2$,那么上述的两个必要条件即是充分的,下面将来证明这一点(过程略长,跳过证明可以点击这里)——
证明
下面,先给出一些引理,来对题目做一些转换——
引理1:若$\{a_{i}\}$的1子图非空且连通,则$\{a_{i}\}$合法
如果$\forall 1\le i\le n,a_{i}=1$显然合法,否则任取一个$a_{x}=0$的点$x$和一个$a_{y}=1$的点$y$
考虑$x$到$y$的路径,根据介值定理其中总存在一条边$(x',y')$满足$a_{x'}=0$且$a_{y'}=1$
此时,若$x'$的其余某条出边满足$a_{z}=1$,显然$y'$和$z$无法连通,与1子图连通矛盾
换言之,$a_{x'}$的出边中仅有$a_{y'}=1$(其余都为0),那么操作$x'$即可使$a_{x'}=1$
注意到$x'$和$y$直接相连,因此仍然满足条件,重复此过程即可使$\forall 1\le i\le n,a_{i}=1$
引理2:将$\{a_{i}\}$的1子图每一个连通块中仅保留一个1(其余点都变为0),不影响$\{a_{i}\}$合法性
任取1子图的一个连通块,显然该连通块外与连通块内有边的点必然都是0,注意到这些0如果不操作,那么整个连通块即是独立的(连向恒为0的点可以看作不连)
此时,这个子问题$\{a_{i}\}$的1子图非空且连通(仅有一个1),根据引理1可以操作使得整个连通块均为1,根据结论1也即合法性相同
此时,1子图的每一个连通块仅有一个点,也即不存在$(x,y)\in E$使得$a_{x}=a_{y}=1$
为了保持此性质,构造两种新操作——
移动操作:选择一个$a_{x}=1$和$(x,y)\in E$,若$y$周围不存在1,则交换$a_{x}$和$a_{y}$(注意必然有$a_{y}=0$)
合并操作:选择一个$a_{x}=0$且$x$周围恰存在$\ge 3$个1,将这些1全部变为0并令$a_{x}=1$
(在性质成立时)新操作都可以被原操作得到,且可以保持性质成立
重新考虑存在一个点可以操作的条件,显然等价于可以执行移动或合并操作
另一方面,注意到移动操作不会改变(1子图)连通块数、合并操作会减少连通块数,因此不妨证明如果可以执行移动或合并操作和且1子图连通块数$\ge 3$,经过若干次操作后可以执行合并操作
注意到移动或合并操作后一定可以再执行移动操作,因此即可重复上述过程不断执行合并操作,再根据连通块数为奇数,最终即可使得连通块数为1,进而根据引理1即合法
为了说明上述事情,再给出一些引理——
引理3:若树中存在一个点可以操作,那么一定可以通过若干次操作后改变$a_{rt}$
移动操作可以看作周围恰有1个1的合并操作,因此此证明中将两者都称为合并操作
若$a_{rt}=0$且$rt$周围有奇数个1,直接对$rt$执行合并操作即可
若$rt$周围有偶数个1,考虑这个可以执行的操作必然在$rt$某个儿子的子树内部,归纳此结论并由此改变该儿子,进而即有奇数个1,再对$rt$执行合并操作即可
若$a_{rt}=1$,那么$rt$周围必然都是0,且若其中一个儿子有偶数个儿子为1(算上$rt$即周围有奇数个1),那么直接对该点执行合并操作即可
若不存在上述的儿子,可以执行的操作必然在某个儿子的儿子子树内部,根据归纳将该儿子的儿子修改,再对该儿子执行合并操作即可
引理4:若树中不能执行移动或合并操作、$a_{rt}=0$且树中存在至少一个1,那么若增加一个$a_{rt}$的父亲且其权值为1,那么经过若干次操作后可以执行合并操作
若$rt$的所有儿子均为0,直接移动到$a_{rt}$后可以看作$rt$某个子树内含有1的儿子的子问题,归纳此结论即可在该子问题内执行合并操作
若$rt$存在奇数个儿子为1,显然初始可以执行操作,与条件矛盾
若$rt$存在偶数个儿子为1,那么即可对$rt$执行合并操作,即结论成立
由此,选择一个点$rt$满足其度数$\ge 3$且将其删除后存在两个连通块点数$\ge 2$,并以其为根建树
先根据引理3,若$a_{rt}=1$则修改$a_{rt}=0$,再对为1的儿子数分类讨论:
1.若为偶数,任选一个子树内可以操作的儿子,根据引理3修改该儿子,即变为奇数的情况
2.若为奇数且$\ge 3$,直接对$rt$执行合并操作即可
3.若为1,考虑其余儿子的子树,分类讨论——
(1)若存在两个子树内可以操作,将这两个子树的根由引理3修改,然后即可对$rt$执行合并操作
(2)若存在某个子树内不全为0且无法执行操作,那么将这个为1的儿子移动到根后,该子树即满足引理4,也即可在该子树内执行合并操作
(3)不为以上情况,即至多一个子树内可以操作,其余子树全部为0,那么不全为0的子树至多只有两个,因此可以将这个为1的儿子移动到某个全部为0的子树
此时,若满足之前的(1)或(2)则继续按照(1)或(2)执行,否则即仍为(3),那么若这个1所在的子树大小为1,其他子树中不全为0的子树至多只有一个,因此可以将这个1再移动到某个全部为0且点数$\ge 2$的子树
若不存在某个子树可以操作,不难发现整棵树此时仅含有这1个1,也即连通块数为1,与条件矛盾
否则再根据引理3,将那个可以操作的子树的根(即$rt$的儿子)变为1,并将原来的1向下移动一步,使这个新的1也移动到某个全部为0的子树(这个子树大小不要求$\ge 2$)
此时,若满足之前的(1)或(2)则继续按照(1)或(2)执行,否则即仍为(3),不难发现此时整棵树仅含有这两个1,也即连通块数为2,与条件矛盾
由此,即说明了可以执行合并操作
综上,即得证
总结
由此,问题即可用树形dp解决,令$f_{k,0/1,0/1,0/1,0/1}$表示以$k$为根的子树中,$a_{k},\bigoplus_{son}a_{son},$1子图连通块个数奇偶性和是否存在一个点可以操作(不包括$k$)为给定值时的方案数,显然容易转移
另外,当不存在之前所述的点时,不难发现原树必然为一条链、链的两端额外有若干条出边
结论3:若$\{a_{i}\}$合法,存在一种方案使得不将链的端点从1变成0,使得$\forall 1\le i\le n,a_{i}=1$
如果存在,取最后一次此类操作,并不妨假设是左端点
由于其最终为1,因此之后必然要再操作将其变回1,而中间必然要再操作一个与其相邻的点(否则没有意义),注意到之前的点无法操作,因此只能操作链上出边的点
以此类推,最终即需要操作右端点,注意到之前的点无法操作,因此右端点之后必须再操作一次,其中总有一次是从1变成0,即与与最后一次矛盾
因此,当两个端点全为1时,将链中间的点划分为若干个极长全0或1的区间,显然其中只有长度大于1的区间端点可以操作(注意整条链的端点不能操作),即不会减少区间数,因此只能初始全部为1
对于额外的出边,显然是任意的,只需要将权值为0的再操作一次即可
当端点中有0时,如果端点可以操作,不妨直接操作并根据结论1,两者合法性相同
如果不可以操作端点,那么当整条链全为0时即无解,否则将与端点相连的极长的一段0依次操作即可(最后操作端点),同样根据结论1合法性相同
根据以上的分析,假设链长为$l$(指链上的点数),链的两个端点额外的出边数分别为$x$和$y$(为了方便,不妨假设$x,y\ne 0$,否则可以将原来的端点作为额外的出边),对端点分类讨论:
1.若两端点都为1,此时需要保证链上全部为1,方案数即为$2^{x+y}$
2.若两端点中恰有一个1,那么链上只能有与其中一个端点相连的一段0,注意到不论长度如何,都要保证该端点可以/不可以操作,因此方案数即为$(l-1)2^{x+y}$(注意这已经乘上端点的2了)
3.若两端点中没有0,对是否全部为0分类讨论——
(1)若全部为0,那么即需要保证恰有一个端点可以操作,方案数即为$2^{x+y-1}$
(2)若不全部为0,同样每一组方案对应于唯一的能否操作,方案数即为${l-1\choose 2}2^{x+y-2}$
(对于$l=1$的情况可以特判,但不难发现答案是相同的)
时间复杂度均为$o(n)$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define mod 998244353
5 #define ll long long
6 #define Add(x,y) x=(x+y)%mod
7 struct Edge{
8 int nex,to;
9 }edge[N<<1];
10 int n,E,x,y,flag,ans,mi[N],head[N],d[N],sz[N],g[2][2][2][2],f[N][2][2][2][2];
11 void add(int x,int y){
12 edge[E].nex=head[x];
13 edge[E].to=y;
14 head[x]=E++;
15 }
16 void dfs(int k,int fa){
17 sz[k]=f[k][0][0][0][0]=f[k][1][0][1][0]=1;
18 int tot=0;
19 for(int i=head[k];i!=-1;i=edge[i].nex){
20 int u=edge[i].to;
21 if (u!=fa){
22 dfs(u,k);
23 tot+=(sz[u]>=2),sz[k]+=sz[u];
24 memcpy(g,f[k],sizeof(g));
25 memset(f[k],0,sizeof(f[k]));
26 for(int a=0;a<2;a++)
27 for(int b=0;b<2;b++)
28 for(int c=0;c<2;c++)
29 for(int d=0;d<2;d++)
30 for(int aa=0;aa<2;aa++)
31 for(int bb=0;bb<2;bb++)
32 for(int cc=0;cc<2;cc++)
33 for(int dd=0;dd<2;dd++)
34 Add(f[k][a][b^aa][c^cc^(a&aa)][d|dd|(a^bb)],(ll)g[a][b][c][d]*f[u][aa][bb][cc][dd])%mod;
35 }
36 }
37 if (n-sz[k]>=2)tot++;
38 if ((d[k]>=3)&&(tot>=2))flag=1;
39 }
40 int main(){
41 mi[0]=1;
42 for(int i=1;i<N;i++)mi[i]=2*mi[i-1]%mod;
43 scanf("%d",&n);
44 memset(head,-1,sizeof(head));
45 for(int i=1;i<n;i++){
46 scanf("%d%d",&x,&y);
47 d[x]++,d[y]++;
48 add(x,y),add(y,x);
49 }
50 dfs(1,0);
51 if (flag){
52 for(int a=0;a<2;a++)
53 for(int b=0;b<2;b++)
54 for(int d=0;d<2;d++)
55 if (b|d)Add(ans,f[1][a][b][1][d]);
56 printf("%d\n",ans);
57 return 0;
58 }
59 x=y=1;
60 for(int i=1;i<=n;i++)
61 if (d[i]>=3){
62 if (x==1)x=d[i]-1;
63 else y=d[i]-1;
64 }
65 int l=n-x-y;
66 printf("%d\n",((ll)l*mi[x+y]+mi[x+y-1]+(ll)(l-1)*(l-2)/2%mod*mi[x+y-2])%mod);
67 return 0;
68 }
[atAGC052F]Tree Vertices XOR的更多相关文章
- CF1055F Tree and XOR
CF1055F Tree and XOR 就是选择两个数找第k大对儿 第k大?二分+trie上验证 O(nlognlogn) 直接按位贪心 维护可能的决策点(a,b)表示可能答案的对儿在a和b的子树中 ...
- 解题:CF1055F Tree and XOR
题面 树上路径是可以通过到根的路径和LCA差出来的,所以建立一棵Trie树按位贪心即可......吗? 发现空间并不够,需要我们每层现建,要记录每个数和它异或答案之后在这一层插进去的编号 #inclu ...
- [atAGC052B]Tree Edges XOR
定义两点的距离$d(x,y)$为$x$到$y$路径上边权异或和,则两棵树相同当且仅当$\forall 1\le i\le n$,$d(1,i)$相同 新建一个节点0,连边$(0,1)$,初始权值为0, ...
- Codeforces 461B. Appleman and Tree[树形DP 方案数]
B. Appleman and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- BZOJ3282: Tree
传送门 又是权限题= =,过了NOIp我就要去当一只权限狗! LCT裸题,get到了两个小姿势. 1.LCA操作应该在access中随时updata 2.Link操作可以更简单 void Link(i ...
- CF461B Appleman and Tree (树DP)
CF462D Codeforces Round #263 (Div. 2) D Codeforces Round #263 (Div. 1) B B. Appleman and Tree time l ...
- codeforces 375D:Tree and Queries
Description You have a rooted tree consisting of n vertices. Each vertex of the tree has some color. ...
- CF 461B Appleman and Tree 树形DP
Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other ...
- Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)
题目链接 D. Appleman and Tree time limit per test :2 seconds memory limit per test: 256 megabytes input ...
随机推荐
- t-SNE 从入门到放弃
t-SNE 算法 1 前言 t-SNE 即 t-distributed stochastic neighbor embedding 是一种用于降维的机器学习算法,在 2008 年由 Laurens v ...
- 解决VSCODE"因为在此系统上禁止运行脚本"报错
在VSCODE中使用yarn,结果报错: 找了下原因,是因为PowerShell执行策略的问题. 解决方法: 以管理员身份运行vscode; 执行:get-ExecutionPolicy,显示R ...
- vue 动态菜单以及动态路由加载、刷新采的坑
需求: 从接口动态获取子菜单数据 动态加载 要求只有展开才加载子菜单数据 支持刷新,页面显示正常 思路: 一开始比较乱,思路很多.想了很多 首先路由和菜单共用一个全局route, 数据的传递也是通过s ...
- Python中is与==区别
1.在Python中,id是什么?id是内存地址,那就有人问了,什么是内存地址呢? 你只要创建一个数据(对象)那么都会在内存中开辟一个空间,将这个数据临时加在到内存中,那么这个空间是有一个唯一标识的, ...
- 数据库已经存在表, django使用inspectdb反向生成model实体类
1.通过inspectdb处理类,可以将现有数据库里的一个或者多个.全部数据库表生成Django model实体类 python manage.py inspectdb --database defa ...
- Eureka使用总结
关于Eureka: 提供基于 REST的服务,在集群中主要用于服务管理.使用该框架,可以将业务组件注册到Eureka容器中,这些组件可进行集群部署,Eureka主要维护这些服务的列表并自动检查他们的状 ...
- Docker--harbor私有仓库部署与管理
目录 一.Harbor简介 二.Harbor 部署 三.维护管理Harbor 一.Harbor简介 1.什么是Harbor ? Harbor 是 VMware 公司开源的企业级 Docker Re ...
- 无网环境安装docker之--rpm
总体思路:找一台可以联网的linux,下载docker的RPM依赖包而不进行安装(yum localinstall),将所有依赖的rpm环境打包好,再在无网环境中解压逐一安装(rpm: --forc ...
- 占位符,SQL注入?
这两天在上课时被同学拿了一段代码问我,这段代码有什么问题,我看了一会说:Connection和PreparedStatement都没关.他说不止这方面的问题,还有sql注入的问题,我就坚决的说使用了占 ...
- kafka生产者和消费者api的简单使用
kafka生产者和消费者api的简单使用 一.背景 二.需要实现的功能 1.生产者实现功能 1.KafkaProducer线程安全的,可以在多线程中使用. 2.消息发送的key和value的序列化 3 ...