洛谷P4494 [HAOI2018]反色游戏(tarjan)
题面
题解
我们先来考虑一个联通块,这些关系显然可以写成一个异或方程组的形式,形如\(\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)的更多相关文章
- P4494 [HAOI2018]反色游戏
P4494 [HAOI2018]反色游戏 题意 给你一个无向图,图上每个点是黑色或者白色.你可以将一条边的两个端点颜色取反.问你有多少种方法每个边至多取反一次使得图上全变成白色的点. 思路 若任意一个 ...
- [BZOJ5303][HAOI2018]反色游戏(Tarjan)
暴力做法是列异或方程组后高斯消元,答案为2^自由元个数,可以得60分.但这个算法已经到此为止了. 从图论的角度考虑这个问题,当原图是一棵树时,可以从叶子开始唯一确定每条边的选择情况,所以答案为1. 于 ...
- 【BZOJ5303】[HAOI2018]反色游戏(Tarjan,线性基)
[BZOJ5303][HAOI2018]反色游戏(Tarjan,线性基) 题面 BZOJ 洛谷 题解 把所有点全部看成一个\(01\)串,那么每次选择一条边意味着在这个\(01\)串的基础上异或上一个 ...
- bzoj 5393 [HAOI2018] 反色游戏
bzoj 5393 [HAOI2018] 反色游戏 Link Solution 最简单的性质:如果一个连通块黑点个数是奇数个,那么就是零(每次只能改变 \(0/2\) 个黑点) 所以我们只考虑偶数个黑 ...
- 【loj#2524】【bzoj5303】 [Haoi2018]反色游戏(圆方树)
题目传送门:loj bzoj 题意中的游戏方案可以转化为一个异或方程组的解,将边作为变量,点作为方程,因此若方程有解,方程的解的方案数就是2的自由元个数次方.我们观察一下方程,就可以发现自由元数量=边 ...
- [BZOJ5303] [HAOI2018] 反色游戏
题目链接 LOJ:https://loj.ac/problem/2524 BZOJ:https://lydsy.com/JudgeOnline/problem.php?id=5303 洛谷:https ...
- bzoj 5303: [Haoi2018]反色游戏
Description Solution 对于一个有偶数个黑点的连通块,只需要任意两两配对,并把配对点上的任一条路径取反,就可以变成全白了 如果存在奇数个黑点的连通块显然无解,判掉就可以了 如果有解, ...
- [HAOI2018]反色游戏
[Luogu4494] [BZOJ5303] [LOJ2524] LOJ有数据就是好 原题解,主要是代码参考 对于每一个联通块(n个点),其他的边一开始随便选,只需要n-1条边就可以确定最终结果. 所 ...
- 题解 [HAOI2018]反色游戏
题目传送门 题目大意 给出一个 \(n\) 个点 \(m\) 条无向边的图,每个点都有一个 \(\in [0,1]\) 的权值,每次可以选择一条边,然后将该边相连两点权值异或上 \(1\).问有多少种 ...
随机推荐
- WARNING: cell0 mapping not found - not syncing cell0
WARNING: cell0 mapping not found - not syncing cell0
- S3C6410的启动代码分析 一
本文开始第一篇,启动代码的编写,注意,仅仅是启动代码,并不是bootloader,因为只有boot,没有loader. 第一要明确:CPU上电之后,会从某个固定地址执行指令.ARM结构的CPU从地址0 ...
- 在linux中read、write函数
read函数从打开的设备或文件中读取数据. #include<</span>unistd.h> ssize_t read(int fd, void *buf, size_t ...
- 【原创】8. MYSQL++中的Row类型
一.mysqlpp::Row类型 在之前的介绍中我们看到了如何通过mysqlpp::Query找到各种Result类型,然后又仔细分析了各种Result类型又是如何生成对应的Row类型(如下所示). ...
- 如何上传网站程序(文件浏览器上传网页、FileZilla上传网站程序)
问题场景: 网页制作完成后,程序需上传至虚拟主机. 注意事项: Windows系统的主机请将全部网页文件直接上传到FTP根目录,即 / . Linux系统的主机请将全部网页文件直接上传到 /htdoc ...
- google/dense_hash_map
这个库使用时需要注意的地方: 1.在插入数据之前,需要先调用set_empty_key()设置一个空Key,Key的值可以为任意符合类型的.但请注意之后插入的Key不能和空Key相同,否则会abort ...
- Html Meta标签记录
记录学习过程中碰到的meta标签 方便今后查阅 X-UA-Compatible: 设置浏览器兼容 如<meta http-equiv="X-UA-Compatible" co ...
- mongo_2 $in 和 $all 区别
in 只需满足( )内的某一个值即可, 而$all 必须满足[ ]内的所有值, > db.table1.find({}); { "_id" : ObjectId(" ...
- 如何撤回经由Outlook2016刚发出的邮件
在Outlook2016中,刚发出了一封邮件,发现有问题,想撤回,如何处理? 在对方尚未查看和接收时,可撤回. 参考步骤 1.选中这封邮件,用鼠标双击打开 2.点Move旁边的下拉按钮 3.点击&qu ...
- 面试题:HTTP必知必会——常见面试题总结 背1
1.常用的HTTP方法有哪些?GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器POST:用于传输信息给服务器,主要功能与GET方法类似,但一般推荐使用POST ...