[HAOI2018]反色游戏
[Luogu4494] [BZOJ5303] [LOJ2524]
LOJ有数据就是好
对于每一个联通块(n个点),其他的边一开始随便选,只需要n-1条边就可以确定最终结果.
所以设\(cnt\)为联通块数 , 答案为 \(2^{m-n+cnt}\)
还有就是有解的情况必须是黑点个数为偶数,还要注意有删掉这个点可能使无解变有解,这比从有解变无解更难想
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
}
const int MAXN=100005;
const int MAXM=200005;
const int mod=1e9+7;
struct Edge{
int v,w,c,next;
}e[MAXM];
int first[MAXN],Ecnt=1;
inline void Add_edge(int u,int v,int w=0,int c=0){
e[++Ecnt]=(Edge){v,w,c,first[u]};
first[u]=Ecnt;
}
int ctg[MAXN],size[MAXN],sub[MAXN],low[MAXN],dfn[MAXN],deg[MAXN],cut[MAXN],pow2[MAXN];
bool flag[MAXN];
char S[MAXN];
int n,m,T,ans,odd,dft,cnt,rt;
inline void clear(){
memset(size,0,sizeof size);
memset(deg,0,sizeof deg);
memset(sub,0,sizeof sub);
memset(cut,0,sizeof cut);
memset(low,0,sizeof low);
memset(dfn,0,sizeof dfn);dft=0;
memset(first,0,sizeof first);Ecnt=0;
cnt=0,odd=0;
}
inline void tarjan(int u,int pre=0){
low[u]=dfn[u]=++dft;
flag[u]=1;
size[u]=(S[u]=='1');//算黑点数量
ctg[u]=rt;//这种情况下方便后面调用
for(int i=first[u];i;i=e[i].next){
int v=e[i].v;
if(!dfn[v]){
tarjan(v,u);
size[u]+=size[v];
if(low[v]>=dfn[u]){
cut[u]++;
flag[u]&=((size[v]&1)==0);//子树不合法可以直接标记
sub[u]+=size[v];
}
else low[u]=min(low[u],low[v]);
}
else if (v!=pre) low[u]=min(low[u],dfn[v]);
}
if(!pre) cut[u]--;//删掉u以后能增加几个连通分量
}
int main(){
pow2[0]=1;
for(int i=1;i<MAXN;i++) pow2[i]=(pow2[i-1]<<1)%mod;
T=read();
while(T--){
n=read(),m=read();
clear();
for(int i=1;i<=m;i++){
int x=read(),y=read();
Add_edge(x,y);
Add_edge(y,x);
deg[x]++,deg[y]++;
}
scanf("%s",S+1);
for(int i=1;i<=n;i++) if(!dfn[i]){
//ctgn++;//这里不适合这样用
rt=i,cnt++;
tarjan(i);
odd+=size[i]&1;
}
ans=m-n+cnt;
printf("%d",odd?0:pow2[ans]);//只要有偶数个黑点就是无解的
for(int i=1;i<=n;i++){
if(!deg[i]) printf(" %d",odd-size[i]==0?pow2[ans]:0);//以后复杂题目估计都得写成这样
else{
//子树合法 父亲那一块合法 也许不合法变为合法
if((flag[i]) && (((size[ctg[i]]-(S[i]=='1')-sub[i])&1)==0) && (odd-(size[ctg[i]]&1)==0))
printf(" %d",pow2[ans-deg[i]+1+cut[i]]);
else printf(" 0");
}
}
printf("\n");
}
}
[HAOI2018]反色游戏的更多相关文章
- 【BZOJ5303】[HAOI2018]反色游戏(Tarjan,线性基)
[BZOJ5303][HAOI2018]反色游戏(Tarjan,线性基) 题面 BZOJ 洛谷 题解 把所有点全部看成一个\(01\)串,那么每次选择一条边意味着在这个\(01\)串的基础上异或上一个 ...
- bzoj 5393 [HAOI2018] 反色游戏
bzoj 5393 [HAOI2018] 反色游戏 Link Solution 最简单的性质:如果一个连通块黑点个数是奇数个,那么就是零(每次只能改变 \(0/2\) 个黑点) 所以我们只考虑偶数个黑 ...
- P4494 [HAOI2018]反色游戏
P4494 [HAOI2018]反色游戏 题意 给你一个无向图,图上每个点是黑色或者白色.你可以将一条边的两个端点颜色取反.问你有多少种方法每个边至多取反一次使得图上全变成白色的点. 思路 若任意一个 ...
- 【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 ...
- [BZOJ5303][HAOI2018]反色游戏(Tarjan)
暴力做法是列异或方程组后高斯消元,答案为2^自由元个数,可以得60分.但这个算法已经到此为止了. 从图论的角度考虑这个问题,当原图是一棵树时,可以从叶子开始唯一确定每条边的选择情况,所以答案为1. 于 ...
- bzoj 5303: [Haoi2018]反色游戏
Description Solution 对于一个有偶数个黑点的连通块,只需要任意两两配对,并把配对点上的任一条路径取反,就可以变成全白了 如果存在奇数个黑点的连通块显然无解,判掉就可以了 如果有解, ...
- Luogu4494 [HAOI2018]反色游戏 【割顶】
首先发现对于一个联通块有奇数个黑点,那么总体来说答案无解.这个很容易想,因为对每个边进行操作会同时改变两个点的颜色,异或值不变. 然后一个朴素的想法是写出异或方程进行高斯消元. 可以发现高斯消元的过程 ...
- 洛谷P4494 [HAOI2018]反色游戏(tarjan)
题面 传送门 题解 我们先来考虑一个联通块,这些关系显然可以写成一个异或方程组的形式,形如\(\oplus_{e\in edge_u}x_e=col_u\) 如果这个联通块的黑色点个数为奇数,那么显然 ...
随机推荐
- Android 创建项目出现No resource found that matches the given name Theme.AppCompat.Light
关于为何出现No resource found that matches the given name ‘Theme.AppCompat.Light’的原因 这边博客已经写的很清楚了 大家可以参考一下 ...
- resolve或reject之后还需要return吗
答案: 需要 今日碰到一个问题, 是我的同事发现的,如果不说的话可能一直没有注意到 这个代码 在reject 后还会执行, 但是谁也没有注意到, 但是不会报错, 因为当一个promise是resolv ...
- SSL认证
SSL认证 单向认证 1.发一串消息个对方 2.对方用私钥加密后返回 3.本方用对方的公钥解密,验证消息是否正确, 如果消息相同,则本方认可对方 双向认证 本方认证对方 对方认证本方
- 面试题:cook和session
1.首先,Cookie与Session存在的目的是什么? 答:二者都是为了保持客户端访问用户与后台服务器的交互状态,之所以为了保持这种状态,一是为了方便一些业务的实现,另一方面就是为了简化后台服务端的 ...
- C++ 输出精度和输出小数点位数
有时候需要调节小数点的精度或者位数 #include<iostream> #include<iomanip> using namespace std; //设置数据精度 set ...
- Django--admin后台
需求 通过后台和models操作数据库表 实现 1.后台中看到数据库中的表 app01/admin.py 1 2 from app01 import models admin.site.regist ...
- FreeMarker 的空值处理 , 简单理解 , 不用TMD就会忘记
NO.1 而对于FreeMarker来说,null值和不存在的变量是完全一样的 NO.2 ! 指定缺失变量的默认值 返回String NO.3 ?? 判断变量是否存在 返回boolean NO.4 $ ...
- Android N 新特性
2016年5月19日,谷歌在美国加州的山景城举办了 Google I/O 开发者大会中发布.2016年6月,Android N正式命名为“牛轧糖” 本届I/O开发者大会上,Google重点介绍了And ...
- 《the art of software testing》 第三章 人工测试
在深入研究较为传统的计算机测试技术之前,要先进行"人工测试". 代码检查与走查是两种主要的人工测试方法. 代码检查与走查是对过去桌面检查过程(在提交测试前由程序员阅读自己程序的过程 ...
- Eclipse中连接数据库错误:com.microsoft.sqlserver.jdbc.SQLServerException: 之类的错误
原创 错误:org.apache.jasper.JasperException: Unable to compile class for JSP 原因是页面指令中 import="java. ...