1 条题解

  • 0
    @ 2025-8-24 22:03:47

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Ebola
    来证个定理吧!

    搬运于2025-08-24 22:03:47,当前版本为作者最后更新于2019-02-17 12:08:20,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    其实做法是和楼下本质上一样的,但本篇题解利用了异或运算使得结论的猜想与证明更加自然

    题目中的条件其实就是说:fi,j=fi1,j1fi1,j+1f_{i,j}=f_{i-1,j-1}\oplus f_{i-1,j+1},其中\oplus表示异或

    不难推出结论:$f_{i,j}=f_{i-2^k,j-2^k}\oplus f_{i-2^k,j+2^k},\quad k\in\mathbb{N}$。数学归纳法证明如下:

    1. k=0k=0时,这就是题目给出的条件
    2. k>0k>0时,假设结论对于k1k-1成立,则有:$f_{i,j}=f_{i-2^{k-1},j-2^{k-1}}\oplus f_{i-2^{k-1},j+2^{k-1}}=(f_{i-2^{k},j-2^{k}}\oplus f_{i-2^{k},j})\oplus(f_{i-2^{k},j}\oplus f_{i-2^{k},j+2^k})=f_{i-2^k,j-2^k}\oplus f_{i-2^k,j+2^k}$

    于是问题就变得非常简单了。将TT二进制分解,然后套用上述结论推logT\log T行就行了,复杂度O(nlogT)O(n\log T)

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int N=100010;
    int n,f[2][N],p=0;
    char s[N];
    LL T;
    
    int main()
    {
        cin>>n>>T>>s;
        for(int i=0;i<n;i++) f[0][i]=s[i]-'0';
        for(int k=0;k<60;k++)if(T&(1ll<<k))
        {
            int pr=(1ll<<k)%n,pl=(n-pr)%n;
            for(int i=0;i<n;i++)
            {
                f[p^1][i]=f[p][pl]^f[p][pr];
                if(++pl>=n) pl-=n;
                if(++pr>=n) pr-=n;
            }
            p^=1;
        }
        for(int i=0;i<n;i++)
            printf("%d",f[p][i]);
        return 0;
    }
    
    • 1

    信息

    ID
    3831
    时间
    1000ms
    内存
    250MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者