zoukankan      html  css  js  c++  java
  • CodeForces 1270I Xor on Figures

    CodeForces 1270I Xor on Figures

    https://codeforces.com/contest/1270/problem/I

    有一个 (2^k imes 2^k(1 le k le 9)) 的网格,其中 ((i,j)) 位置上的数字为 (a_{i,j}(0 le a_{i,j} < 2^{60})) .

    这个网格是循环的,即 ((i,2^k)) 的右边是 ((i,1)) , ((2^k,i)) 的下面是 ((1,i))

    有一个网格图(不一定联通) (F) ,它包含 (t) 个两两不同的格子(((1 le t le min{99,4^k}))(t) 为奇数) ((x_1,y_1),(x_2,y_2),cdots,(x_t,y_t)(1 le x_i,y_i le 2^k)) .

    一次操作可以选择一个格子 ((x,y)(1 le x,y le 2^k)) 和一个数字 (p) ,然后令所有 ((x+x_i mod 2^k,y+y_i mod 2^k)(1le i le t)) 上的数字异或 (p) .

    问至少需要多少次操作令所有格子中的数 (=0) .若不存在,输出 (-1)

    Tutorial

    https://www.luogu.com.cn/problem/solution/CF1270I

    定义新矩阵乘法 (A imes B =C) ,其中

    [C(x,y) = sum_{a=0}^{2^k-1} sum_{b=0}^{2^k-1} A(a,b)B(x-a mod 2^k,y-b mod 2^k) ]

    则我们需要的就是找到是否存在这样一个矩阵 (C) ,满足 (C imes F = A) ,且 (C) 中非零数的位置最少.

    假如我们可以找到 (F) 在新矩阵乘法意义下面的逆元.那么可以证明 (C) 是存在且唯一的.

    考虑 (F imes F) 的形状,其中有贡献的位置是 ((x_i+x_j mod 2^k,y_i+y_j mod 2^k)(1 le i,j le t)) 的形式.考虑若 (i ot= j) 那么 ((i,j),(j,i)) 分别贡献一次后这个位置上的数就会变为 (0) .

    所以最后 (F imes F) 的所有非零位置就是 ((2x_i mod 2^k,2y_i mod 2^k)) .

    那么 (F^{2^k}) 的所有非零位置就是 ((2^kx_i mod 2^k,2^ky_i mod 2^k)=(0,0)) ,而由于 (t) 是奇数,所以总是有奇数个 (1) ,所以 ((0,0)) 位置上最后为 (1) .而这相当于在新矩阵乘法意义下的单位矩阵 (I)

    [F^{2^k} = I \ F^{2^k-1}=F^{-1} ]

    [C=A imes F^{-1} = A imes F^{2^k-1} = A imes prod_{i=0}^{k-1} F^{2^i} ]

    由于 (F) 中的非零位置只有 (t) 个,所以一次新矩阵乘法的复杂度是 (O(4^kt)) 的.

    总时间复杂度 (O(kt4^k))

    Code

    #include <cassert>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #define fi first
    #define se second
    using namespace std;
    inline char nc()
    {
        static char buf[100000],*l=buf,*r=buf;
        return l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
    }
    template<class T> void read(T &x)
    {
        x=0; int f=1,ch=nc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=nc();}
        while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=nc();}
        x*=f;
    }
    typedef long long ll;
    typedef pair<int,int> pii;
    const int maxk=9;
    const int maxn=1<<maxk;
    const int maxt=99;
    int k;
    int n;
    int t;
    ll a[2][maxn][maxn];
    pii F[maxt];
    inline int add(int x) {return x>=n?x-n:x;} 
    inline int sub(int x) {return x<0?x+n:x;}
    int main()
    {
        // freopen("in.txt","r",stdin);
        read(k),n=1<<k;
        int cur=0;
        for(int i=0;i<n;++i) for(int j=0;j<n;++j)
        {
            read(a[cur][i][j]);
        }
        read(t);
        for(int i=0;i<t;++i)
        {
            read(F[i].fi),read(F[i].se);
        }
        for(int i=0;i<k;++i)
        {
            cur^=1;
            memset(a[cur],0,sizeof(a[cur]));
            for(int x=0;x<n;++x) for(int y=0;y<n;++y)
            {
                for(int j=0;j<t;++j)
                {
                    a[cur][x][y]^=a[cur^1][sub(x-F[j].fi)][sub(y-F[j].se)];
                }
            }
            for(int j=0;j<t;++j)
            {
                F[j].fi=add(F[j].fi<<1);
                F[j].se=add(F[j].se<<1);            
            }
        }
        int an=0;
        for(int x=0;x<n;++x) for(int y=0;y<n;++y)
        {
            if(a[cur][x][y]) ++an;
        }
        printf("%d
    ",an);
        return 0;
    }
    
  • 相关阅读:
    jquery操作select(取值,设置选中)
    POST 服务测试PHP页面
    Web开发者不容错过的20段CSS代码(二)
    Web开发者不容错过的20段CSS代码(一)
    Word排版技巧
    需求分析的故事——如何练就需求分析的火眼金晴?
    如何来书写需求说明书
    Struts配置文件阐释
    做需求要会问为什么和需求场景
    跑通并调试第一个Java Struts程序
  • 原文地址:https://www.cnblogs.com/ljzalc1022/p/13031383.html
Copyright © 2011-2022 走看看