好神呀…
手玩一下发现这个H(s)生成的串有个斐波那契的递推式
emmmmm然后我就啥都不会了….
我们定义G(s)为H(s)的逆变换,即H(a)=b,G(b)=a
那么对于s中的每个1,如果后面是0,他会变成1,否则变成0
发现我们要验证s是否是S的子串,这个问题等价于验证G(s)是否是G(S)的子串
我们可以不断对s做逆变换,让他越来越短
我们先来证几个结论
1:
Hn
H
n
的偶数项最后一位是0,奇数项最后一位是1
2:
Hn(n>0)
H
n
(
n
>
0
)
第一位为1
3:
Hn
H
n
中不存在00
4:
Hn(n为奇数且n>=5)
H
n
(
n
为
奇
数
且
n
>=
5
)
最后有一段10101
5:
Hn(n为奇数且n>=5)
H
n
(
n
为
奇
数
且
n
>=
5
)
后面不能接0 (由性质4,若接0,101010,对
Hn
H
n
逆变换2次后会有00项,一定不是S的子串(由性质2))
用发现的那个斐波那契性质易证
然后考虑对s做逆变换
s由很多个 Hai H a i 拼在一起,当ai都>0时, Hai(i<n) H a i ( i < n ) 后面都跟着一个1(结论2),所以不用考虑后面的东西对 Hai H a i 逆变换的影响, G(Hai)=Hai−1 G ( H a i ) = H a i − 1 直接ai-=1
对于
Han
H
a
n
,
若an为偶数,s最后一位时0,s后面的东西不会影响G(s),直接an–,
若an为奇数,当an=1时,因为s后面可以跟1或0,发现此时an不影响整个s是否是S的子串,直接将an删去;an=3时,同样可以删去最后一个1,让an=2,an-=1变成1;an>=5时,因为后面不能接0,可以直接an-=1
一直这样缩直到出现
ai=0
a
i
=
0
,这时不能再分别缩了因为没有
G(H0)
G
(
H
0
)
这个东西,要将他和前面合并
对于一个位置
ai=0
a
i
=
0
,
若
ai−1
a
i
−
1
是偶数,出现00不合法
若
ai−1
a
i
−
1
是奇数
1:
ai−1=1
a
i
−
1
=
1
,合并在一起,
ai−1=2
a
i
−
1
=
2
2:
ai−1=3
a
i
−
1
=
3
,变成1010,
ai−1=ai=2
a
i
−
1
=
a
i
=
2
3:
ai−1>=5
a
i
−
1
>=
5
,出现101010,不合法
因为 ∑ni=1ai<=1e7 ∑ i = 1 n a i <= 1 e 7 操作直接暴力过整个序列就行了
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
inline void read(int &x)
{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
const int maxn = 1100000;
int n,m;
int a[maxn];
int main()
{
int tcase; read(tcase);
while(tcase--)
{
read(n);
for(int i=1;i<=n;i++) read(a[i]);
bool flag=true;
while(n>1&&flag)
{
if(a[n]==1) n--;
else if(a[n]==3) a[n]=2;
for(int i=1;i<=n;i++) if(!a[i])
{
if(i==1) a[i]=2;
else
{
int j=i-1; if(!a[j]) j--;
if(a[j]&1)
{
if(a[j]>=5) { flag=false; break; }
else if(a[j]==1) a[j]=2;
else a[j]=a[i]=2;
}
else { flag=false; break; }
}
}
m=0; for(int i=1;i<=n;i++) if(a[i]) a[++m]=a[i]-1;
n=m;
}
puts(flag?"TAK":"NIE");
}
return 0;
}