传送门
手玩样例发现发现2^k变换之后,第i个位置的硬币情况只与它左右的第k+1个硬币有关。
如k=0,第3位硬币情况只与2和4位硬币有关。因为t可以拆成若干个2^k的和,于是对每个2^k进行O(n)的变换,总复杂度O(nlogt)。
#include<cstring>
#include<cmath>
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#define ll long long
using namespace std;
ll a[200005],b[200005],n,t;
ll f(ll b,ll q){
ll x=((b-q)%(2*n)+2*n-1)%(2*n)+1;
ll y=(b+q-1)%(2*n)+1;
if (!q) return a[x];
if (!a[x]) return 0;
if (a[x]!=a[y]) return 2;
return 1;
}
void work(ll k,ll q){
if (k==0) return;
work(k/2,q*2);
if (k%2){
memset(b,0,sizeof(b));
for (ll j=1;j<=n*2;j++) b[j]=f(j,q);
swap(a,b);
}
}
int main(){
scanf("%lld%lld",&n,&t);
for (int i=1;i<=n;i++) scanf("%lld",&a[i*2-1]);
work(t,1);
for (int i=1;i<2*n;i++) printf("%lld ",a[i]);
printf("%lld",a[n*2]);
}