题目传送门:loj bzoj

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

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

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

  代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cmath>
  4. #include<cstdlib>
  5. #include<algorithm>
  6. #define ll long long
  7. #define inf 0x3f3f3f3f
  8. #define mod 1000000007
  9. #define maxn 200010
  10. inline ll read()
  11. {
  12. ll x=; char c=getchar(),f=;
  13. for(;c<''||''<c;c=getchar())if(c=='-')f=-;
  14. for(;''<=c&&c<='';c=getchar())x=x*+c-'';
  15. return x*f;
  16. }
  17. inline void write(ll x)
  18. {
  19. static int buf[],len; len=;
  20. if(x<)x=-x,putchar('-');
  21. for(;x;x/=)buf[len++]=x%;
  22. if(!len)putchar('');
  23. else while(len)putchar(buf[--len]+'');
  24. }
  25. inline void writeln(ll x){write(x); putchar('\n');}
  26. inline void writesp(ll x){write(x); putchar(' ');}
  27. struct edge{
  28. int to,nxt;
  29. };
  30. struct Graph{
  31. edge e[*maxn];
  32. int fir[*maxn],deg[*maxn];
  33. int tot;
  34. inline void clear()
  35. {
  36. memset(fir,,sizeof(fir)); tot=;
  37. memset(deg,,sizeof(deg));
  38. }
  39. inline void add_edge(int x,int y)
  40. {
  41. e[tot].to=y; e[tot].nxt=fir[x]; fir[x]=tot++;
  42. ++deg[x];
  43. }
  44. }G,T;
  45. int dfn[maxn],low[maxn],st[maxn],ans[maxn];
  46. int val[*maxn],size[*maxn],fa[*maxn],rt[*maxn];
  47. char s[maxn];
  48. int n,m,tot,tp,cnt;
  49. inline ll power(ll a,ll b)
  50. {
  51. ll ans=;
  52. for(;b;b>>=,a=a*a%mod)
  53. if(b&)ans=ans*a%mod;
  54. return ans;
  55. }
  56. void tarjan(int now,int last)
  57. {
  58. dfn[now]=low[now]=++tot; st[++tp]=now;
  59. for(int i=G.fir[now];~i;i=G.e[i].nxt)
  60. if(i!=(last^)){
  61. if(!dfn[G.e[i].to]){
  62. tarjan(G.e[i].to,i);
  63. low[now]=std::min(low[now],low[G.e[i].to]);
  64. if(low[G.e[i].to]>=dfn[now]){
  65. ++cnt;
  66. T.add_edge(now,cnt); T.add_edge(cnt,now);
  67. do{
  68. T.add_edge(st[tp],cnt); T.add_edge(cnt,st[tp]);
  69. }while(st[tp--]!=G.e[i].to);
  70. }
  71. }
  72. else low[now]=std::min(low[now],dfn[G.e[i].to]);
  73. }
  74. }
  75. void dfs(int now,int root)
  76. {
  77. rt[now]=root;
  78. size[now]=val[now];
  79. for(int i=T.fir[now];~i;i=T.e[i].nxt)
  80. if(T.e[i].to!=fa[now]){
  81. fa[T.e[i].to]=now;
  82. dfs(T.e[i].to,root);
  83. size[now]+=size[T.e[i].to];
  84. }
  85. }
  86. void work()
  87. {
  88. n=read(); m=read();
  89. G.clear();
  90. for(int i=;i<=m;i++){
  91. int x=read(),y=read();
  92. G.add_edge(x,y); G.add_edge(y,x);
  93. }
  94. scanf("%s",s);
  95. memset(val,,sizeof(val));
  96. for(int i=;i<=n;i++)
  97. val[i]=(s[i-]=='');
  98. T.clear();
  99. memset(dfn,,sizeof(dfn));
  100. memset(low,,sizeof(low));
  101. tot=tp=; cnt=n;
  102. for(int i=;i<=n;i++)
  103. if(!dfn[i]){
  104. tarjan(i,-);
  105. fa[i]=-;
  106. dfs(i,i);
  107. }
  108. int odd=,block=;
  109. for(int i=;i<=n;i++)
  110. if(fa[i]==-)odd+=(size[i]&),++block;
  111. ans[]=(odd?:power(,m-n+block));
  112. for(int i=;i<=n;i++){
  113. odd-=(size[rt[i]]&);
  114. int flag=;
  115. for(int j=T.fir[i];~j;j=T.e[j].nxt)
  116. if(T.e[j].to!=fa[i]&&(size[T.e[j].to]&)){
  117. flag=; break;
  118. }
  119. if(odd||!flag||((size[rt[i]]-size[i])&))ans[i]=;
  120. else ans[i]=power(,(m-G.deg[i])-(n-)+(block+T.deg[i]-));
  121. odd+=(size[rt[i]]&);
  122. }
  123. for(int i=;i<=n;i++)
  124. writesp(ans[i]);
  125. putchar('\n');
  126. }
  127. int main()
  128. {
  129. int T=read();
  130. while(T--)work();
  131. return ;
  132. }

反色游戏

【loj#2524】【bzoj5303】 [Haoi2018]反色游戏(圆方树)的更多相关文章

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

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

  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. P4494 [HAOI2018]反色游戏

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

  6. bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树)

    bzoj5315/luoguP4517 [SDOI2018]战略游戏(圆方树,虚树) bzoj Luogu 题目描述略(太长了) 题解时间 切掉一个点,连通性变化. 上圆方树. $ \sum |S| ...

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

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

  8. [SDOI2018]战略游戏 圆方树,树链剖分

    [SDOI2018]战略游戏 这题是道路相遇(题解)的升级版,询问的两个点变成了\(S\)个点. LG传送门 还是先建出圆方树,考虑对于询问的\(S\)个点,答案就是圆方树上能包含这些点的最小连通块中 ...

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

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

随机推荐

  1. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_16-异常处理-可预知异常处理-自定义异常类型和抛出类

    在common工程创建捕获异常的类:CustomException Runtime叫做运行异常.在代码中抛出的话 对我们的代码没有可侵入性 如果在代码上抛出 如果改成Exception 这时候就会有错 ...

  2. Selenium下Chrome配置 (含启动无痕界面)

    例子: 设置无界面模式浏览器启动chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--headless') ...

  3. Sql 中常用日期转换Convert(Datetime) convert datetime

    Convert(data_type,expression[,style]) Convert(varchar(10),字段名,转换格式) 说明:此样式一般在时间类型(datetime,smalldate ...

  4. JQ也要面向对象~在JQ中扩展静态方法和实例方法(jq扩展方法)

    JQ也要面向对象,事实上,无论哪种开发语言,在开发功能时,都要把面向对象拿出来,用它的思想去干事,去理解事,面向对象会使问题简单化,清晰化,今天说两个概念“静态方法”与“实现方法”,这个在面向对象的语 ...

  5. CMake版本升级

    CMake 是一个可扩展的开源系统,以独立于编译器的方式在操作系统中管理生成过程.与许多跨平台系统不同,CMake 旨在与本机生成环境结合使用.放置在每个源目录中的简单配置文件(称为 CMakeLis ...

  6. C#操作Memcached帮助类

    在VS中安装Memcached,直接在NuGet下搜索Memcached,选择第一个进行安装: 服务端资源下载地址:https://pan.baidu.com/s/1gf3tupl 接下来开始写程序, ...

  7. 监听input框变化,即时搜索 compositionstart, compositionend

    前话: 如果直接通过input监听, 它是键盘输入按键按下了就触发时间,这样可能导致一些问题,比如在谷歌浏览器想输入中文输入不了: 解决方案: 用 compositionstart 和 composi ...

  8. eNSP——通过Stelnet登录系统

    Stelnet的原理 由于Telnet缺少安全的认证方式,而且传输过程采用TCP进行明文传输,存在很大的安全隐患,单纯提供Telnet服务容易招致主机IP地址欺骗.路由欺骗等恶意攻击.传统的Telne ...

  9. 洛谷 题解 P1133 【教主的花园】

    $n<=10^5 $ O(n)算法 状态 dp[i][j][k]表示在第i个位置,种j*10的高度的树,且这棵树是否比相邻两棵树高 转移 dp[i][1][0]=max(dp[i-1][2][1 ...

  10. Spring实例化Bean三种方法:构造器、静态工厂、实例工厂

    Spring中Bean相当于java中的类,可以通过xml文件对bean进行配置和管理. 一.Bean的实例化: 构造器实例化.静态工厂实例化.实例工厂方式实例化. 目录: 构造器实例化: xml配置 ...