巨魔沒金幣
題目描述
某巨魔去了一趟拍賣行賣東西,賺了不少金幣,然後又買了些東西,就沒金幣了。
該巨魔沒了金幣,但他還有很多銀幣。
他搞了張圓桌。劃分出
接下來每次按如下操作:在任意兩個銀幣之間放上一個銀幣,然後將原來的銀幣拿走;
所放銀幣的正反面由它兩邊的兩個銀幣決定,若兩個銀幣均爲正面朝上或反面朝上,則所放銀幣爲正面朝上,否則爲反面朝上。
那麼操作
輸入格式
第一行包含兩個整數
接下的一行包含
輸出格式
輸出一行
樣例輸入
10 5
2 2 2 1 1 1 1 1 1 2
樣例輸出
0 1 0 1 0 1 0 1 0 2 0 1 0 2 0 1 0 1 0 1
數據範圍
Solution
若將每一位上的數字減
打表發現,進行
那麼,我們可以將
Summary
考場上我是發現了
進行
2k 次操作後,i 位上的數字爲i−2k 與i+2k 上的數字的異或值(將n 個數字向左、右無限複製)
的規律的。
但當時特別腦殘,認爲這個規律只能做一個特判,即
Code
#include <iostream>
#include <cstdio>
#define LL long long
using namespace std;
LL n,t;
LL w[200010];
LL tot[200010];
void work(LL x){
LL tmp=1;
while(tmp<=x)tmp<<=1;
tmp>>=1;
while(x){
while(tmp>x)tmp>>=1;
for(int i=1;i<=2*n;i++){tot[i]=w[i];w[i]=-1;}
if(tot[1]!=-1&&tmp==1||tot[1]==-1&&tmp!=1)
for(int i=2;i<=2*n;i+=2){
w[i]=tot[(((i-tmp)-1)%(2*n)+2*n)%(2*n)+1]^tot[((i+tmp)-1)%(2*n)+1];
}
else
for(int i=1;i<=2*n;i+=2){
w[i]=tot[(((i-tmp)-1)%(2*n)+2*n)%(2*n)+1]^tot[(((i+tmp)-1)%(2*n)+2*n)%(2*n)+1];
}
x-=tmp;
}
}
int main(){
freopen("silver.in","r",stdin);
freopen("silver.out","w",stdout);
scanf("%lld%lld",&n,&t);
for(int i=1;i<=n;i++){
w[2*i]=-1;
scanf("%lld",&w[2*i-1]);
w[2*i-1]--;
}
work(t);
for(int i=1;i<=2*n;i++)printf("%d ",w[i]+1);
return 0;
}