BZOJ2303: [Apio2011]方格染色
2014-02-28 10:02
253 查看
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2303
题目简述:有一个包含n × m个方格的表格,每个方格可以涂红色或蓝色,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 个或 3 个)红色方格。有些格子已经被确定颜色,剩下的格子可以自行染色。求满足条件的方案数MOD(10^9)。
哎这数据太弱了,,考试随便写了个。。神坑算法 ,就过了80分,剩下两个点还是因为爆栈。
首先一个没有一个是固定的,答案就是2^(n+m-1)。这个随便搞zhao一gui下lv就行了。记p=n+m-1
神坑算法:先看他给出来的是否有冲突,没有冲突就找他给出来的东西的所有极大联通块。对每个联通块找一个最小的矩形把他包起来,令这个矩形的长宽为a,b
,然后p-=(a+b-1)。。然后所有矩形搞完了就算2^p。 哎哎。。
正规算法:
其实试一下就会发现,奇数行和偶数行分别是有规律的。若第i行是奇数行且i行中第x列和第y列的颜色是一样的,那么所有奇数行的第x列和第y列的颜色都是一样的。偶数行亦然。且一行只要确定了一个,整行就固定了。为了简化问题,所以把所有相同的关系搞到第一二行上去,并查集维护关系(相同或不同)。
再新建两个虚拟点,一个代表红色,一个代表蓝色, 红色蓝色之间连不同!!!!!<-用来判断冲突。!!
如果并查集加的时候有问题。那直接输出0.
第一二行的异同情况搞出来之后,再考虑第一二行的关系,发现同一列颜色上下的关系只可能是 同 不同 同 不同 ....或者 不同 同 不同 同。
分别按两种方法再把刚才处理出来的并查集连上,若没有冲突,再看有几个集合。
若该集合和红蓝虚拟点有链接,说明这个集合的颜色是固定的。答案是*1 ,就是不变。
若和红蓝节点没有连接,说明他有两种方法(10, 01),这时答案*2。
然后把两个情况的答案加起来。
最后还要看3-n行是不是每一行都有限制,若有一行没有限制,那他也有两种颜色选择,所以答案和还要乘一个2^没有限制的行的个数。
他的题解算法就不说了(meikandong)。但应该思路都是基本相同的。
题目简述:有一个包含n × m个方格的表格,每个方格可以涂红色或蓝色,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 个或 3 个)红色方格。有些格子已经被确定颜色,剩下的格子可以自行染色。求满足条件的方案数MOD(10^9)。
哎这数据太弱了,,考试随便写了个。。神坑算法 ,就过了80分,剩下两个点还是因为爆栈。
首先一个没有一个是固定的,答案就是2^(n+m-1)。这个随便搞zhao一gui下lv就行了。记p=n+m-1
神坑算法:先看他给出来的是否有冲突,没有冲突就找他给出来的东西的所有极大联通块。对每个联通块找一个最小的矩形把他包起来,令这个矩形的长宽为a,b
,然后p-=(a+b-1)。。然后所有矩形搞完了就算2^p。 哎哎。。
正规算法:
其实试一下就会发现,奇数行和偶数行分别是有规律的。若第i行是奇数行且i行中第x列和第y列的颜色是一样的,那么所有奇数行的第x列和第y列的颜色都是一样的。偶数行亦然。且一行只要确定了一个,整行就固定了。为了简化问题,所以把所有相同的关系搞到第一二行上去,并查集维护关系(相同或不同)。
再新建两个虚拟点,一个代表红色,一个代表蓝色, 红色蓝色之间连不同!!!!!<-用来判断冲突。!!
如果并查集加的时候有问题。那直接输出0.
第一二行的异同情况搞出来之后,再考虑第一二行的关系,发现同一列颜色上下的关系只可能是 同 不同 同 不同 ....或者 不同 同 不同 同。
分别按两种方法再把刚才处理出来的并查集连上,若没有冲突,再看有几个集合。
若该集合和红蓝虚拟点有链接,说明这个集合的颜色是固定的。答案是*1 ,就是不变。
若和红蓝节点没有连接,说明他有两种方法(10, 01),这时答案*2。
然后把两个情况的答案加起来。
最后还要看3-n行是不是每一行都有限制,若有一行没有限制,那他也有两种颜色选择,所以答案和还要乘一个2^没有限制的行的个数。
他的题解算法就不说了(meikandong)。但应该思路都是基本相同的。
#include <cstdio> #include <algorithm> typedef long long LL; inline int getx(){ char c;int x; for (c=getchar();c<'0'||c>'9';c=getchar()); for (x=0;c>='0'&&c<='9';c=getchar()) x=(x<<3)+(x<<1)+c-'0'; return x; } struct Point{ int x,y;short color; Point(int _x = 0,int _y = 0,short _c = 0):x(_x),y(_y),color(_c){} }; bool operator <(const Point &a,const Point &b){return a.x<b.x||(a.x==b.x&&a.y<b.y);} const LL MOD=(int)1e9; const int MAX_N=100005; int fa[MAX_N*2];bool delta[MAX_N*2]; int tfa[MAX_N*2];bool tdelta[MAX_N*2]; Point a[MAX_N]; int n,m,k,p; #define black (2*m+1) #define white (2*m+2) //a==b 0 //a!=b 1 int getfa(int x){ if (fa[x]!=x){ int tp=fa[x]; fa[x]=getfa(fa[x]); delta[x]=(delta[x]+delta[tp])%2; } return fa[x]; } inline bool merge(int x,int y,int c){ int A=getfa(x),B=getfa(y); if (A==B){ int tp=(delta[x]+2-delta[y])%2; if (tp!=c) return false; }else{ fa[A]=B; delta[A]=(2-delta[x]+c+delta[y])%2; } return true; } inline bool work(int l,int r){ int row=(a[l].x&1)?0:m; for (int i=l;i<r;++i) if (!merge(row+a[i].y,row+a[i+1].y,a[i].color!=a[i+1].color)) return false; return true; } LL power(LL a,LL b){ LL res=1; for (;b;a=a*a%MOD,b>>=1) if (b&1) res=res*a%MOD; return res; } bool pd[MAX_N*2]; LL ans=0; bool work2(){ for (int i=1;i<=2*m+2;++i) tfa[i]=fa[i],tdelta[i]=delta[i]; bool ck1=true,ck2=true; int num=0; for (int i=1;i<=m;++i) if (!merge(i,m+i,(i&1)==1)){ck1=false;break;} if (ck1){ for (int i=1;i<=m;++i){ int A=getfa(i); if (!pd[A]){pd[A]=true;if (A!=getfa(white)&&A!=getfa(black)) num++;} } ans+=power(2,num); } num=0; for (int i=1;i<=2*m+2;++i) fa[i]=tfa[i],delta[i]=tdelta[i],pd[i]=0; for (int i=1;i<=m;++i) if (!merge(i,m+i,(i&1)==0)){ck2=false;break;} if (ck2){ for (int i=1;i<=m;++i){ int A=getfa(i); if (!pd[A]){pd[A]=true;if (A!=getfa(white)&&A!=getfa(black)) num++;} } (ans+=power(2,num))%=MOD; } return ck1||ck2; } int main(){ freopen("color.in","r",stdin); freopen("color.out","w",stdout); n=getx(),m=getx(),k=getx(); for (int i=1;i<=2*m+2;++i) fa[i]=i,delta[i]=0; merge(black,white,1);//这都没加!!! for (int i=1;i<=k;++i) a[i].x=getx(),a[i].y=getx(),a[i].color=getx(); std::sort(a+1,a+k+1); int vis=0,last=1; for (int i=1;i<=k;++i) if (a[i].x!=a[i+1].x){ if (a[i].x<=2){ int f=(a[i].x==1?0:m); for (int j=last;j<=i;++j) if (!merge(f+a[i].y,a[i].color?black:white,0)){printf("0");exit(0);} }else vis++; if (!work(last,i)){printf("0");exit(0);} last=i+1; } p=n-2-vis; if (!work2()) {printf("0");exit(0);} printf("%I64d\n",power(2,p)*ans%MOD); }
相关文章推荐
- 【BZOJ2303】【Apio2011】方格染色 异或方程+并查集
- [杂题 异或 带权并查集] BZOJ2303: [Apio2011]方格染色
- [BZOJ2303]-[Apio2011]方格染色-并查集+题目性质
- BZOJ2303 APIO2011方格染色
- BZOJ2303: [Apio2011]方格染色
- BZOJ2303 APIO2011方格染色(并查集)
- [BZOJ2303][Apio2011]方格染色(数学相关+加权并查集)
- [BZOJ2303][APIO2011]方格染色 异或+并查集
- BZOJ2303: [Apio2011]方格染色
- BZOJ_2303_[Apio2011]方格染色 _并查集
- bzoj 2303: [Apio2011]方格染色
- [BZOJ]2303: [Apio2011]方格染色 并查集
- bzoj 2303 Apio2011 方格染色
- 2303: [Apio2011]方格染色
- 【bzoj 2303】【Apio2011】方格染色
- BZOJ 2303: [Apio2011]方格染色 题解
- BZOJ 2303: [Apio2011]方格染色 并查集神题
- BZOJ 2303: [Apio2011]方格染色 [并查集 数学!]
- [BZOJ 2303][Apio2011]方格染色:并查集
- bzoj 2303: [Apio2011]方格染色 (并查集)