【loj#2524】【bzoj5303】 [Haoi2018]反色游戏(圆方树)
题目传送门: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]反色游戏(圆方树)相关推荐
- [BZOJ5303] [HAOI2018] 反色游戏
题目链接 LOJ:https://loj.ac/problem/2524 BZOJ:https://lydsy.com/JudgeOnline/problem.php?id=5303 洛谷:https ...
- LOJ.2587.[APIO2018]铁人两项Duathlon(圆方树)
题目链接 LOJ 洛谷P4630 先对这张图建圆方树. 对于S->T这条(些)路径,其对答案的贡献为可能经过的所有点数,那么我们把方点权值设为联通分量的大小,可以直接去求树上路径权值和. 因为两 ...
- [BZOJ5329][Sdoi2018]战略游戏 圆方树+虚树
5329: [Sdoi2018]战略游戏 Time Limit: 30 Sec Memory Limit: 512 MB Submit: 174 Solved: 109 [Submit][Stat ...
- BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- [SDOI2018]战略游戏 圆方树+虚树
Description 给T组数据. 每组数据给你一个n个点的无向图,保证图联通,给q个询问. 每个询问给k个节点,问每一次询问中,求有多少个点在断掉他之后可以使图中两个点不连通. Sample In ...
- Luogu4606 SDOI2018 战略游戏 圆方树、虚树、链并
传送门 弱化版 考虑到去掉一个点使得存在两个点不连通的形式类似割点,不难想到建立圆方树.那么在圆方树上对于给出的关键点建立虚树之后,我们需要求的就是虚树路径上所有圆点的数量减去关键点的数量. 因为没有 ...
- P4494-[HAOI2018]反色游戏【圆方树】
正题 题目链接:https://www.luogu.com.cn/problem/P4494 题目大意 给出nnn个点mmm条边的一张无向图,节点有0/10/10/1,每条边可以选择是否取反两边的点. ...
- [bzoj5329][圆方树][虚树]战略游戏
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- 【SDOI2018】战略游戏【圆方树】【虚树】
题意:给一张 nnn 点 mmm 边的连通无向图,qqq 次询问,每次给出一个点集 SSS ,求有多少个不在 SSS 中的点满足删除后 SSS 中存在两个点不连通. n≤105,m≤2×105,∑∣S ...
最新文章
- Python 语法小知识
- numpy.random.randint详解
- Nebula:Slack 的覆盖全球性的开源网络
- docker 常用命令 以及常见问题
- 2021年KTV行业发展蓝皮书
- Cinema 4D R25 for mac(c4d r25)快捷键分享
- 网易云音乐的所有歌手列表
- 系统论的应用——心理学
- 网页中超长图片转成pdf文档
- 教新手了解怎么从网络中赚钱
- 通过CURL请求示例详解HTTPS协议
- 百度地图AK鉴权说明与白名单设置方法
- (ICASSP 19)AUTOMATIC GRAMMAR AUGMENTATION FOR ROBUST VOICE COMMAND RECOGNITION
- 科学史专家们竟把中国的算盘当成最早的计算机?这个博物馆为你展示计算机2000年历史
- 循环神经网络(RNN)简单介绍及实现(基于表面肌电信号)
- Word Puzzles
- 模拟飞行 android,微软模拟飞行手机版
- 使用ADK(windows评估和部署工具包)制作PE
- 群体机器人kilobots研究文章推荐(群体智能)
- TvInput Cec key事件传递流程
热门文章
- GVA gin-vue-admin前后端部署教程
- Go gin内嵌静态资源go-bindata的安装及使用(GVA)
- k8s API编程:kubebuilder实战案例sidecarset
- arthas命令整理:基础命令、jvm相关、class相关命令
- Scala 键盘录入对象StdIn/特质/伴生对象
- unsigned int 和 int
- python如何在循环中保存文件_Python中如何将爬取到的数据循环存入到csv文件中?...
- 8080端口被占用_Spring Cloud IPv6端口问题排坑
- cmd小游戏编程100例_学宏程序编程,这些知识必不可少!
- github/gitee码云文件上传提交记录教程