题目传送门:loj bzoj

  题意中的游戏方案可以转化为一个异或方程组的解,将边作为变量,点作为方程,因此若方程有解,方程的解的方案数就是2的自由元个数次方。我们观察一下方程,就可以发现自由元数量=边数-点数+连通块数,或者换句话说,若对原图的每个联通块指定一棵生成树,那么确定了生成树之外的边是否进行操作,那么生成树内的边的操作方案就是一定存在并唯一确定的。

  那么我们就只需要判断一下什么样的图无解。我们发现每对一条边进行操作,原图内的黑点数量奇偶性不变,那么我们只需判断图中的是否存在某个联通块有奇数个黑点,若存在即无解。

  加上了删点操作后,我们可以用圆方树来维护连通块信息。因为圆方树的连通性与原图上的连通性相互对应,删除单个点之后,原图被新分成的连通块就是圆方树删除对应点的连通块,那么使用圆方树就可以快速维护删除单个点的连通块信息。

  代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define maxn 200010
inline ll read()
{ll x=0; char c=getchar(),f=1;for(;c<'0'||'9'<c;c=getchar())if(c=='-')f=-1;for(;'0'<=c&&c<='9';c=getchar())x=x*10+c-'0';return x*f;
}
inline void write(ll x)
{static int buf[20],len; len=0;if(x<0)x=-x,putchar('-');for(;x;x/=10)buf[len++]=x%10;if(!len)putchar('0');else while(len)putchar(buf[--len]+'0');
}
inline void writeln(ll x){write(x); putchar('\n');}
inline void writesp(ll x){write(x); putchar(' ');}
struct edge{int to,nxt;
};
struct Graph{edge e[4*maxn];int fir[2*maxn],deg[2*maxn];int tot;inline void clear(){memset(fir,255,sizeof(fir)); tot=0;memset(deg,0,sizeof(deg));}inline void add_edge(int x,int y){e[tot].to=y; e[tot].nxt=fir[x]; fir[x]=tot++;++deg[x];}
}G,T;
int dfn[maxn],low[maxn],st[maxn],ans[maxn];
int val[2*maxn],size[2*maxn],fa[2*maxn],rt[2*maxn];
char s[maxn];
int n,m,tot,tp,cnt;
inline ll power(ll a,ll b)
{ll ans=1;for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;return ans;
}
void tarjan(int now,int last)
{dfn[now]=low[now]=++tot; st[++tp]=now;for(int i=G.fir[now];~i;i=G.e[i].nxt)if(i!=(last^1)){if(!dfn[G.e[i].to]){tarjan(G.e[i].to,i);low[now]=std::min(low[now],low[G.e[i].to]);if(low[G.e[i].to]>=dfn[now]){++cnt;T.add_edge(now,cnt); T.add_edge(cnt,now);do{T.add_edge(st[tp],cnt); T.add_edge(cnt,st[tp]);}while(st[tp--]!=G.e[i].to);}}else low[now]=std::min(low[now],dfn[G.e[i].to]);}
}
void dfs(int now,int root)
{rt[now]=root;size[now]=val[now];for(int i=T.fir[now];~i;i=T.e[i].nxt)if(T.e[i].to!=fa[now]){fa[T.e[i].to]=now;dfs(T.e[i].to,root);size[now]+=size[T.e[i].to];}
}
void work()
{n=read(); m=read();G.clear();for(int i=1;i<=m;i++){int x=read(),y=read();G.add_edge(x,y); G.add_edge(y,x);}scanf("%s",s);memset(val,0,sizeof(val));for(int i=1;i<=n;i++)val[i]=(s[i-1]=='1');T.clear();memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));tot=tp=0; cnt=n;for(int i=1;i<=n;i++)if(!dfn[i]){tarjan(i,-1);fa[i]=-1;dfs(i,i);}int odd=0,block=0;for(int i=1;i<=n;i++)if(fa[i]==-1)odd+=(size[i]&1),++block;ans[0]=(odd?0:power(2,m-n+block));for(int i=1;i<=n;i++){odd-=(size[rt[i]]&1);int flag=1;for(int j=T.fir[i];~j;j=T.e[j].nxt)if(T.e[j].to!=fa[i]&&(size[T.e[j].to]&1)){flag=0; break;}if(odd||!flag||((size[rt[i]]-size[i])&1))ans[i]=0;else ans[i]=power(2,(m-G.deg[i])-(n-1)+(block+T.deg[i]-1));odd+=(size[rt[i]]&1);}for(int i=0;i<=n;i++)writesp(ans[i]);putchar('\n');
}
int main()
{int T=read();while(T--)work();return 0;
}

反色游戏

转载于:https://www.cnblogs.com/quzhizhou/p/11483149.html

【loj#2524】【bzoj5303】 [Haoi2018]反色游戏(圆方树)相关推荐

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

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

  2. LOJ.2587.[APIO2018]铁人两项Duathlon(圆方树)

    题目链接 LOJ 洛谷P4630 先对这张图建圆方树. 对于S->T这条(些)路径,其对答案的贡献为可能经过的所有点数,那么我们把方点权值设为联通分量的大小,可以直接去求树上路径权值和. 因为两 ...

  3. [BZOJ5329][Sdoi2018]战略游戏 圆方树+虚树

    5329: [Sdoi2018]战略游戏 Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 174  Solved: 109 [Submit][Stat ...

  4. BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)

    Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...

  5. [SDOI2018]战略游戏 圆方树+虚树

    Description 给T组数据. 每组数据给你一个n个点的无向图,保证图联通,给q个询问. 每个询问给k个节点,问每一次询问中,求有多少个点在断掉他之后可以使图中两个点不连通. Sample In ...

  6. Luogu4606 SDOI2018 战略游戏 圆方树、虚树、链并

    传送门 弱化版 考虑到去掉一个点使得存在两个点不连通的形式类似割点,不难想到建立圆方树.那么在圆方树上对于给出的关键点建立虚树之后,我们需要求的就是虚树路径上所有圆点的数量减去关键点的数量. 因为没有 ...

  7. P4494-[HAOI2018]反色游戏【圆方树】

    正题 题目链接:https://www.luogu.com.cn/problem/P4494 题目大意 给出nnn个点mmm条边的一张无向图,节点有0/10/10/1,每条边可以选择是否取反两边的点. ...

  8. [bzoj5329][圆方树][虚树]战略游戏

    Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...

  9. 【SDOI2018】战略游戏【圆方树】【虚树】

    题意:给一张 nnn 点 mmm 边的连通无向图,qqq 次询问,每次给出一个点集 SSS ,求有多少个不在 SSS 中的点满足删除后 SSS 中存在两个点不连通. n≤105,m≤2×105,∑∣S ...

最新文章

  1. Python 语法小知识
  2. numpy.random.randint详解
  3. Nebula:Slack 的覆盖全球性的开源网络
  4. docker 常用命令 以及常见问题
  5. 2021年KTV行业发展蓝皮书
  6. Cinema 4D R25 for mac(c4d r25)快捷键分享
  7. 网易云音乐的所有歌手列表
  8. 系统论的应用——心理学
  9. 网页中超长图片转成pdf文档
  10. 教新手了解怎么从网络中赚钱
  11. 通过CURL请求示例详解HTTPS协议
  12. 百度地图AK鉴权说明与白名单设置方法
  13. (ICASSP 19)AUTOMATIC GRAMMAR AUGMENTATION FOR ROBUST VOICE COMMAND RECOGNITION
  14. 科学史专家们竟把中国的算盘当成最早的计算机?这个博物馆为你展示计算机2000年历史
  15. 循环神经网络(RNN)简单介绍及实现(基于表面肌电信号)
  16. Word Puzzles
  17. 模拟飞行 android,微软模拟飞行手机版
  18. 使用ADK(windows评估和部署工具包)制作PE
  19. 群体机器人kilobots研究文章推荐(群体智能)
  20. TvInput Cec key事件传递流程

热门文章

  1. GVA gin-vue-admin前后端部署教程
  2. Go gin内嵌静态资源go-bindata的安装及使用(GVA)
  3. k8s API编程:kubebuilder实战案例sidecarset
  4. arthas命令整理:基础命令、jvm相关、class相关命令
  5. Scala 键盘录入对象StdIn/特质/伴生对象
  6. unsigned int 和 int
  7. python如何在循环中保存文件_Python中如何将爬取到的数据循环存入到csv文件中?...
  8. 8080端口被占用_Spring Cloud IPv6端口问题排坑
  9. cmd小游戏编程100例_学宏程序编程,这些知识必不可少!
  10. github/gitee码云文件上传提交记录教程