CF461D-Appleman and Complicated Task【并查集】

1|0正题

题目链接:https://www.luogu.com.cn/problem/CF461D


1|1题目大意

nn的网格需要填上xo,其中有k个格子已经固定,求有多少中填写方案使得每个格子的四周都有偶数个o


1|2解题思路

约束条件相当于一个格子周围的异或和都为0,也就是对于任意(x,y)都有ax1,y xor ax,y1 xor ax+1,y xor ax,y+1。也就是对于一个格子(x,y)也有ax,y=ax1,y1 xor ax1,y+1 xor ax2,y

根据以上我们可以发现对于一个格子的值都可以由第一行的某些格子的异或和来表示,且它们格子的奇偶相同。

从这个蓝色格子来看,它的值等于黄色格子和青色格子的异或和。

其中两个黄色格子又都包括了青色格子,所以相互抵消,中间缺失的青色格子回本蓝色本身补回来,而周围的绿色格子不会被抵消。

所以能够发现其实蓝色格子的异或和就等于某一行里被红线夹着的同奇偶的格子的异或和。

这样我们对于一个固定的点就相等于限制奇或偶的一个区间异或值。

差分完之后就变为了判断两个格子是否相等,用并查集判即可。


1|3code

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=2e5+10; const long long P=1e9+7,inv2=(P+1)/2; int n,k,fa[N]; int find(int x) {return (fa[x]==x)?x:(fa[x]=find(fa[x]));} bool Calc(int l,int r,int w){ if(w){ if(find(l)==find(r))return 0; if(find(l)==find(r+n))return 1; fa[find(r+n)]=find(l); fa[find(l+n)]=find(r); } else{ if(find(l)==find(r+n))return 0; if(find(l)==find(r))return 1; fa[find(r)]=find(l); fa[find(r+n)]=find(l+n); } return 1; } int main() { scanf("%d%d",&n,&k); int p=n;n+=2; for(int i=1;i<=2*n;i++)fa[i]=i; for(int i=1;i<=k;i++){ int x,y;char w[2]; scanf("%d%d%s",&x,&y,&w);x--;y--; int l=abs(x-y),r=min(x+y,2*(p-1)-x-y)+2; if(!Calc(l,r,w[0]=='o')) return puts("0")&0; } long long ans=inv2*inv2%P,z=0; for(int i=0;i<2*n;i++) if(find(i)==i)z++;z/=2; while(z)z--,ans=ans*2%P; printf("%lld\n",ans); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/14292625.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(55)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示