zoukankan      html  css  js  c++  java
  • CF 1270I

    链接

    按位考虑的话,相当于是每一位在 (mod 2) 意义下做循环卷积,该位上有一个 (G*F=T) ,其中 (F,G) 给定(每一位的 (F) 一样)。

    我们尝试找这个 (F) 在循环卷积意义下的逆。

    首先我们不妨设 ([x^0y^0] F= 1) 可以通过让所有位置循环的移动来实现这件事。

    考虑 (F^2) ,考虑两个为 (1) 的位置 ((x_1,y_1))((x_2,y_2)) 显然 ((x_2,y_2), (x_1,y_1)) 也会有贡献,因为是异或这两个抵消掉了。

    于是原来的 ((x,y)) 会在取平方后变成 ((2x,2y))

    容易发现 (F^{(2^k)}) 恰好等于 (1)

    于是 (F^{2^k-1})(F) 的一个逆。

    而如果有多个逆,则必定存在一个非 (0)(G) 使得 (GF=0) ,而此时 (G F^{2^k}= 0) ,故 (G = 0)

    于是这个逆是唯一的。故原题解唯一,暴力乘上 (F^{2^k}) 即可。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int k, n, vec;
    const int N = 1<<9;
    ll a[N][N], b[N][N];
    int x[N], y[N];
    
    int main()
    {
    	cin >> k;n=1<<k;
    	for(int i=0;i<n;i++)for(int j=0;j<n;j++)scanf("%lld",&a[i][j]);
    	cin >> vec;
    	for(int i=0;i<vec;i++){
    		scanf("%d%d",&x[i],&y[i]);
    	}
    	for(int i=vec-1;~i;i--){
    		x[i]-=x[0],y[i]-=y[0];
    	}
    	for(int t=0;t<k;t++){
    		for(int i=0;i<n;i++)for(int j=0;j<n;j++)b[i][j]=0;
    		for(int i=0;i<n;i++){
    			for(int j=0;j<n;j++){
    				for(int q=0;q<vec;q++){
    					int nxtx=(i+x[q])&(n-1), nxty=(j+y[q])&(n-1);
    					b[nxtx][nxty]^=a[i][j];
    				}
    			}
    		}
    		for(int i=0;i<n;i++)for(int j=0;j<n;j++)a[i][j]=b[i][j];
    		for(int i=0;i<vec;i++)x[i]=(x[i]*2)&(n-1),y[i]=(y[i]*2)&(n-1);
    	}
    	int ans=0;
    	for(int i=0;i<n;i++){
    		for(int j=0;j<n;j++){
    			if(a[i][j])ans++;
    		}
    	}
    	cout << ans << endl;
    }
    
  • 相关阅读:
    和为S的两个数字
    和为S的连续正数序列
    两个链表的第一个公共结点
    删除链表中重复的结点
    常用开发工具的安装(JDK、IDEA、Tomcat、Maven、Mysql和Nodepad++)——实习日志7.10
    蓄水池取样(转)
    prepare statement
    ProxySQL Getting started
    架构收录
    服务开机自启动
  • 原文地址:https://www.cnblogs.com/weiyanpeng/p/12189324.html
Copyright © 2011-2022 走看看