[ZJOI2009]硬币游戏

 看上去是个dp

也确实有dp的解法,但是看见 $ T\le 2^60 $ ,所以就决定去找找规律

我们知道每个硬币只有正反两种状态 n 是1e5的规模

然后发现当前位置是受两边硬币状态的影响的,且相邻(dp也是相通思路

并且是异或的关系

由于数据规模,我们二进制拆分一下t,然后节约下空间

 

#include<bits/stdc++.h>

#define int long long
using namespace std;
const int N=1e5+7;

int n,m;
int a[3][N],ans[N<<1];
int sum,cnt;

signed main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        int q;
        cin>>q;
        q--;
        a[0][i]=q;
    }
    for(int i=2;i<=m;i<<=1)
    {
        if(m&i)
        {
            cnt++;
            
            for(int j=1;j<=n;j++)
            {
                int x=(j+(i>>1)%n+n-1)%n+1;
                int y=(j-(i>>1)%n+n-1)%n+1;
                
                a[cnt&1][j]=a[~cnt&1][x]^a[~cnt&1][y];
            }
        }
        
    }
    for(int i=1;i<=n;i++)
    ans[(i<<1)-1]=a[cnt&1][i];
    
    if(m&1)
    {
        for(int i=1;i<=n;i++)
        ans[i<<1]=ans[(i<<1)-1]^ans[i==n?1:i<<1|1];
        for(int i=1;i<=n;i++)
        ans[(i<<1)-1]=-1;
    }
    else
    {
        for(int i=1;i<=n;i++)
        ans[i<<1]=-1;
        
    }
    
    for(int i=1;i<=(n<<1);i++)    
        cout<<ans[i]+1<<' ';
    
    
    
    return 0;
}

 

posted @ 2021-08-23 22:14  Hehe_0  阅读(110)  评论(0)    收藏  举报