题面

传送门

题解

我们先来考虑一个联通块,这些关系显然可以写成一个异或方程组的形式,形如\(\oplus_{e\in edge_u}x_e=col_u\)

如果这个联通块的黑色点个数为奇数,那么显然这个方程是无解的

证明:每条边都在方程组的左边出现了两次,左边全部异或起来为\(0\),右边全部异或起来为\(1\),显然无解

那么如果这个方程组有解,解的个数就是\(2^{自由元数目}\)

我们随便求出这个联通块的一棵生成树,把所有树边当成自由元,容易发现对于非树边的每一种选法,树边都有一种唯一对应的选择方案使其合法,设这个联通块边数为\(m\),点数为\(n\),方案数就是\(2^{m-n+1}\)

进一步可得知\(c\)个联通块的方案数为\(2^{m-n+c}\)次,且与联通块内部连边无关

然后是对于每个点的询问,先判一下删掉之后的联通块中是否会有奇数个黑色点,如果合法的话就减去它周围的边数减去它自己的点数再加上新的联通块数即可

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
int read(char *s){
R int len=0;R char ch;while(((ch=getc())>'1'||ch<'0'));
for(s[++len]=ch;(ch=getc())>='0'&&ch<='1';s[++len]=ch);
return s[len+1]='\0',len;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]=' ';
}
const int N=1e5+5,P=1e9+7;
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void Add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int dfn[N],low[N],sz[N],deg[N],ok[N],cut[N],rt[N],bin[N],sub[N];char s[N];
int n,m,u,v,tim,Rt,cnt,odd;
void tarjan(int u,int fa){
sz[u]=s[u]-'0',dfn[u]=low[u]=++tim,ok[u]=cut[u]=sub[u]=0,rt[u]=Rt;
go(u)if(!dfn[v]){
tarjan(v,u),sz[u]+=sz[v],cmin(low[u],low[v]);
low[v]>=dfn[u]?++cut[u],ok[u]|=(sz[v]&1),sub[u]+=sz[v]:0;
}else if(v!=fa)cmin(low[u],dfn[v]);
!fa?--cut[u]:0;
}
void clr(){
memset(dfn,0,sizeof(int)*(n+1)),tim=0;
memset(head,0,sizeof(int)*(n+1)),tot=0;
memset(deg,0,sizeof(int)*(n+1));
}
int main(){
// freopen("testdata.in","r",stdin);
bin[0]=1;fp(i,1,1e5)bin[i]=(bin[i-1]<<1)%P;
for(int T=read();T;--T){
n=read(),m=read();
fp(i,1,m)u=read(),v=read(),++deg[u],++deg[v],Add(u,v),Add(v,u);
read(s),cnt=m-n,odd=0;
fp(i,1,n)if(!dfn[i])Rt=i,tarjan(i,0),++cnt,odd+=(sz[i]&1);
print(odd?0:bin[cnt]);
fp(i,1,n)print((ok[i]||(odd-(sz[rt[i]]&1))||((sz[rt[i]]-s[i]-'0'-sub[i])&1))?0:bin[cnt-deg[i]+cut[i]+1]);
// fp(i,1,n)if(cnt-deg[i]+cut[i]+1>=1e5)puts("qwq");
sr[C]='\n',clr();
}
return Ot(),0;
}

洛谷P4494 [HAOI2018]反色游戏(tarjan)的更多相关文章

  1. P4494 [HAOI2018]反色游戏

    P4494 [HAOI2018]反色游戏 题意 给你一个无向图,图上每个点是黑色或者白色.你可以将一条边的两个端点颜色取反.问你有多少种方法每个边至多取反一次使得图上全变成白色的点. 思路 若任意一个 ...

  2. [BZOJ5303][HAOI2018]反色游戏(Tarjan)

    暴力做法是列异或方程组后高斯消元,答案为2^自由元个数,可以得60分.但这个算法已经到此为止了. 从图论的角度考虑这个问题,当原图是一棵树时,可以从叶子开始唯一确定每条边的选择情况,所以答案为1. 于 ...

  3. 【BZOJ5303】[HAOI2018]反色游戏(Tarjan,线性基)

    [BZOJ5303][HAOI2018]反色游戏(Tarjan,线性基) 题面 BZOJ 洛谷 题解 把所有点全部看成一个\(01\)串,那么每次选择一条边意味着在这个\(01\)串的基础上异或上一个 ...

  4. bzoj 5393 [HAOI2018] 反色游戏

    bzoj 5393 [HAOI2018] 反色游戏 Link Solution 最简单的性质:如果一个连通块黑点个数是奇数个,那么就是零(每次只能改变 \(0/2\) 个黑点) 所以我们只考虑偶数个黑 ...

  5. 【loj#2524】【bzoj5303】 [Haoi2018]反色游戏(圆方树)

    题目传送门:loj bzoj 题意中的游戏方案可以转化为一个异或方程组的解,将边作为变量,点作为方程,因此若方程有解,方程的解的方案数就是2的自由元个数次方.我们观察一下方程,就可以发现自由元数量=边 ...

  6. [BZOJ5303] [HAOI2018] 反色游戏

    题目链接 LOJ:https://loj.ac/problem/2524 BZOJ:https://lydsy.com/JudgeOnline/problem.php?id=5303 洛谷:https ...

  7. bzoj 5303: [Haoi2018]反色游戏

    Description Solution 对于一个有偶数个黑点的连通块,只需要任意两两配对,并把配对点上的任一条路径取反,就可以变成全白了 如果存在奇数个黑点的连通块显然无解,判掉就可以了 如果有解, ...

  8. [HAOI2018]反色游戏

    [Luogu4494] [BZOJ5303] [LOJ2524] LOJ有数据就是好 原题解,主要是代码参考 对于每一个联通块(n个点),其他的边一开始随便选,只需要n-1条边就可以确定最终结果. 所 ...

  9. 题解 [HAOI2018]反色游戏

    题目传送门 题目大意 给出一个 \(n\) 个点 \(m\) 条无向边的图,每个点都有一个 \(\in [0,1]\) 的权值,每次可以选择一条边,然后将该边相连两点权值异或上 \(1\).问有多少种 ...

随机推荐

  1. Python Twisted系列教程8:使用Deferred的诗歌下载客户端

    作者:dave@http://krondo.com/deferred-poetry/  译者:杨晓伟(采用意译) 可以从这里从头开始阅读这个系列. 客户端4.0 我们已经对deferreds有些理解了 ...

  2. spring-boot restful put方式提交表单

    使用spring-boot 做接口,如果按restful的路由形式想使用put方式进行表单提交,第一个参数应该为文件参数,代码如下: @PutMapping("/http-put" ...

  3. 摄影之HDR

    摄影之HDR 高动态范围图像(High-Dynamic Range,简称HDR),相比普通的图像,可以提供更多的动态范围和图像细节,根据不同的曝光时间的LDR(Low-Dynamic Range)图像 ...

  4. Elasticsearch之kopf插件安装之后的浏览详解

    前提, Elasticsearch之插件介绍及安装 https://i.cnblogs.com/posts?categoryid=950999&page=2  (强烈建议,从头开始看) 比如, ...

  5. PHP数据结构之三 线性表中的单链表的PHP实现

    线性表的链式存储:用一组任意的存储单元存储线性表中的数据元素.用这种方法存储的线性表简称线性链表. 链式存储线性表的特点:存储链表中结点的一组任意的存储单元可以是连续的,也可以是不连续的,甚至是零散分 ...

  6. ref & out - C#中的参数传递

    [ref & out - C#中的参数传递] ref与out均指定函数参数按引用传递,惟一的不同是,ref传递的参数必须初始化,而out可以不用. ref与out无法作为重载的依据,即ref与 ...

  7. 因浏览器而异的空白节点(js清除空白节点)

    先看下面的代码:<dl id="dll">  <dt>title</dt>  <dd>definition</dd>&l ...

  8. CentOS7 启动docker.service失败(code=exited, status=1/FAILURE)

    启动报错 Job for docker.service failed because the control process exited with error code. See "sys ...

  9. 张超超OC基础回顾03_结构体类型作为成员变量的特殊用法

    直接上例子: 要求: 合理的设计一个”学生“类 学生有* 姓名* 生日两个属性和说出自己姓名生日方法  要求利用设计的学生类创建学生对象,并说出自己的姓名和年龄 描述学生类 事物名称: 学生(Stud ...

  10. 张超超OC基础回顾01_类的创建,申明属性,以及本质

    一. 类的声明和实现&规则 1.如何编写类的声明 以@interface开头 , 以@end结尾, 然后再class name对应的地方写上 事物名称, 也就是类名即可 注意: 类名的首字符必 ...