zoukankan      html  css  js  c++  java
  • 【CF461D】Appleman and Complicated Task

    题目

    题目链接:https://codeforces.com/problemset/problem/461/D
    给定一个 (n imes n) 的网格,其中 (k) 个位置已经被填充为 O 或 X。
    求有多少种填充剩下的位置为 O 或 X 的方式,使得任意位置四周的 O 的数量均为偶数。
    答案对 (1000000007) 取模。
    (n,kleq 10^5)

    思路

    挺巧妙的一道题。下文所有下标均减一,即范围在 ([0,n)) 内。
    把 O 看做 (1),X 看做 (0),因为四周的格子异或起来等于 (0),所以有 (a_{i,j}=a_{i-1,j-1}mathrm{ xor }a_{i-1,j+1}mathrm{ xor }a_{i-2,j})
    一直这样不断往上算,画个图可以发现,最终位置 ((x,y)) 的网格会被第一行若干连续奇偶相同的网格贡献。具体的,会被第一行 (jin[|x-y|,min(2n-x-y,x+y)])(j)(x+y) 奇偶性相同的格子 ((1,j)) 贡献到。
    第一行的格子做一下前缀异或和,一个位置 ((x,y)) 被强制填 (p) 其实等价于 (a_{1,|x-y|-2}mathrm{ xor }a_{1,min(2n-x-y,x+y)}=p)
    那么现在题意转化为有若干个关于异或的限制,求异或查分后本质不同的序列数量。那么就在 (|x-y|-2)(1,min(2n-x-y,x+y)) 之间连一条边,然后 dfs 求联通块数量即可。
    最终答案要除以 (4),因为 (-1)(-2) 是我们虚构出来的格子,它们任意填数的 (4) 种方案都应该算 (1) 种。
    时间复杂度 (O(n+m))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=100010,MOD=1000000007;
    int n,m,tot,ans,col[N],head[N];
    char ch[3];
    
    struct edge
    {
    	int next,to,dis;
    }e[N*2];
    
    void add(int from,int to,int dis)
    {
    	e[++tot]=(edge){head[from],to,dis};
    	head[from]=tot;
    }
    
    bool dfs(int x,int c)
    {
    	if (col[x] && col[x]==c) return 1;
    	if (col[x] && col[x]!=c) return 0;
    	col[x]=c;
    	for (int i=head[x];~i;i=e[i].next)
    		if (!dfs(e[i].to,e[i].dis^c)) return 0;
    	return 1;
    }
    
    int main()
    {
    	memset(head,-1,sizeof(head));
    	scanf("%d%d",&n,&m);
    	n--;
    	for (int i=1,x,y;i<=m;i++)
    	{
    		scanf("%d%d%s",&x,&y,ch);
    		x--; y--;
    		if (x+y>n)
    		{
    			add(abs(x-y),2*n-x-y+2,ch[0]=='o');
    			add(2*n-x-y+2,abs(x-y),ch[0]=='o');
    		}
    		else
    		{
    			add(abs(x-y),x+y+2,ch[0]=='o');
    			add(x+y+2,abs(x-y),ch[0]=='o');
    		}
    	}
    	ans=1;
    	for (int i=0;i<=n+2;i++)
    		if (!col[i])
    		{
    			if (!dfs(i,2)) return printf("0"),0;
    			ans=ans*2%MOD;
    		}
    	printf("%lld",250000002LL*ans%MOD);
    	return 0;
    }
    
  • 相关阅读:
    我的2015技术学习流水账
    Java程序员的现代RPC指南
    我对读计算机软件专业硕士的几点看法
    Hadoop加速器GridGain
    BDD敏捷开发入门与实战
    openstack kilo部署-基础环境
    python学习之成员信息增删改查
    网站监控系统安装部署(zabbix,nagios)
    监控redis数据库应用状态:python,tornado实现
    python 远程执行命令、发布文件
  • 原文地址:https://www.cnblogs.com/stoorz/p/14292937.html
Copyright © 2011-2022 走看看