[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\) 如果这个联通块的黑色点个数为奇数,那么显然 ...
随机推荐
- Centos7.2 下搭建LNMP环境(终极版)Yum安装
PHP7.1+Nginx+MySQL5.7 安装PHP //安装源只要遇到选择的全是Y rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-rele ...
- 696. Count Binary Substrings统计配对的01个数
[抄题]: Give a string s, count the number of non-empty (contiguous) substrings that have the same numb ...
- 框架和cms区别
cms:精装房,拎包即可入住 框架:毛坯房,内部装修可根据自己需求来 选择策略:个性化需求不高的话,可以选择cms
- Django JSON-RPC
Django JSON-RPC https://github.com/samuraisam/django-json-rpc =============== A basic JSON-RPC Imple ...
- oracle获取表和列的备注
using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Runti ...
- 初次接触URDF
使用URDF创建机器人3D仿真模型 在真实的机器人上编程可以更好地让我们理解机器人的控制方式,因为真实的机器人会有反馈.如果没有真实的机器人,那么ROS仿真是一个很好的选择. ROS通过URDF(Un ...
- java发送post 的json请求
package com.elink.estos.mq.mqmanager; import java.io.IOException; import java.io.InputStream; import ...
- Python基础-5
目录 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 hashlib re正则表达式 模块 ...
- 一步之遥——第七届蓝桥杯C语言B组(国赛)第一题
原创 一步之遥 从昏迷中醒来,小明发现自己被关在X星球的废矿车里.矿车停在平直的废弃的轨道上.他的面前是两个按钮,分别写着“F”和“B”. 小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退.按 ...
- tomcat的内存配置,关于-Xms -Xmx -XX:PermSize -XX:MaxPermSize的理解和区别
JVM按照其存储数据的内容将所需内存分配为堆区与非堆区两个部分:所谓堆区即为通过new的方式创建的对象(类实例)所占用的内存空间:非堆区即为代码.常量.外部访问(如文件访问流所占资源)等.然而虽然ja ...