[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 ...
随机推荐
- 10.13 Nginx 负载均衡
七层负载均衡server { listen 80; server_name localhost; location / { proxy_pass http://name; //调用集群 } } ups ...
- SpringBoot-集成SpringSecurity
在 Web 开发中,安全一直是非常重要的一个方面. 安全虽然属于应用的非功能性需求,但是从应用开发的第一天就应该把安全相关的因素考虑进来,并在整个应用的开发过程中. Spring Security官网 ...
- SpringBoot-自动装配2
配置文件到底能写什么?怎么写? SpringBoot官方文档中有大量的配置,直接去记忆的话,好像不是我们程序员的行事风格! 分析自动配置原理 能自动配置的组件一般都有命名为下面规则的两个类: xxxx ...
- pycharm设置文件中显示模板内容
pycharm中设置自己的文件模板 File>>Settings>>Editor>>File and Code Templates 选择文件类型或者输入文件类型 ...
- C++ 与 Visual Studio 2019 和 WSL(三)
头文件 如果不小心修改了 Linux C/C++ 标准头文件,可以下面这样操作进行恢复: 项目 → 重新扫描解决方案
- 微信小程序的支付流程
一.前言 微信小程序为电商类小程序,提供了非常完善.优秀.安全的支付功能 在小程序内可调用微信的API完成支付功能,方便.快捷 场景如下图所示: 用户通过分享或扫描二维码进入商户小程序,用户选择购买, ...
- Scrum Meeting 13
第13次例会报告 日期:2021年06月05日 会议主要内容概述: 团队成员均明确了下一步的目标,进度突飞猛进辣 一.进度情况 我们采用日报的形式记录每个人的具体进度,链接Home · Wiki,如下 ...
- 单片机stm32串口分析
stm32作为现在嵌入式物联网单片机行业中经常要用多的技术,相信大家都有所接触,今天这篇就给大家详细的分析下有关于stm32的出口,还不是很清楚的朋友要注意看看了哦,在最后还会为大家分享有些关于stm ...
- python write() argument must be str, not bytes
python pickle from __future__ import absolute_import from __future__ import division from __future__ ...
- cesium制作自己的骑行轨迹
制作自己的骑行轨迹 马上国庆节了,计划骑车回家,突然想到把所有的骑行线路汇总一下,无奈码表和APP不支持这样的操作,出于职业病,在此操作一下. 我用的是黑鸟码表,可以导出fit运动轨迹,但是fit还需 ...