P8763
ryf_loser
·
·
题解
2024.3.11 添加第二组演示样例。
2024.3.12 修改第一组演示样例,添加一点点证明。
暴力显然寄飞了,考虑优化,这种情况往往是有规律的,我举两个例子样例进行模拟的。
输入 n=4,t=5,不难发现,从第 4 次就开始循环了。
0. 0110 \leftarrow
1. 0101
2. 0111
3. 0100
4. 0110 \leftarrow
用样例再来搞一下,输入 n=5,t=9
0. 10110
1. 11101 \leftarrow
2. 10011
3. 11010
4. 10111
5. 11100
6. 10010
7. 11011
8. 10110
9. 11101 \leftarrow
有感觉了么?
那么,最终的规律是当大于等于 n 的一个 2 的整数次幂情况下,必定存在循环。
可以证明,令 x=2^k,根据题目。
s_{x,j}=s_{x-1,j}\oplus s_{x-1,j-1}
s_{x-1,j}=s_{x-2,j}\oplus s_{x-2,j-1}
s_{x-1,j-1}=s_{x-2,j-1}\oplus s_{x-2,j-2}
……
由此递推下去,可得。
s_{x,j}=s_{\frac{x}{2},j}\oplus s_{\frac{x}{2},j-x}
根据异或性质可以发现,第 x 的序列是由两次 \frac{x}{2} 的序列得来的。
当 x \geq n 时,这种重复操作变得没有意义,准确来说,当 x \leq n 时必定存在与此时字符串 s 完全相同。
时间复杂度为 O(n \log \min(n,t)) 级别。秒了。
AC CODE
#include<stdio.h>
long long n,t;
int x=1;
char s[10005];
int main(){
scanf ("%lld%lld",&n,&t);
scanf ("%s",s);
while(x<n)x<<=1;t=t%x;
for(int i=0;i<t;i++)
for(int j=n-1;j>=1;j--)
s[j]=(s[j]-'0')^(s[j-1]-'0')+'0';
printf ("%s",s);
return 0;
}