题目链接
- 独立做出来一道银牌题,还是比较开心的;虽然赛场上肯定不会有这么多时间给我消耗的……
- 熟悉了一下bitset的基本语法,读入的时候,注意bitset末位为s[0],而字符串首位为s[0];同时,不要低估其成员函数的时间复杂度
- 通过模拟样例,猜想到s->t等价于0->(s^t);打表找出规律后,似乎只要把规律刻画出来,就能解决本题了
- 于是你迎来了本题的最后一个考验:能否以尽可能简洁直观的语言把规律抽象出来,这将大大影响程序的编程复杂度,也在相当程度上决定了你能不能在赛场上解岀本题。很明显,这次你做得不够好
- 用二进制的视角观察规律显得十分繁琐。考察其中的基本循环结构。考虑将连续两位的二进制编码划为一组,用四进制的视角观察规律
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int mod=1000000007;
const int inv2=500000004;
const int inv3=333333336;
string s,t;
bool m[1000000];
int id;
int step()
{
return id/2+1;
}
int calc(int k)
{
return (power(4,k)-1)*inv3%mod;
}
int ask(int len,int k)
{
if(id==-1)
{
return calc(k);
}
if(!m[len-1])
{
return ask(len-1,k);
}
if(len==id+1&&step()==k)
{
return (calc(len/2+1)*power(2,len%2)-(len%2==0))%mod;
}
else if(len==id+1)
{
if(k==1)
{
if(len%2==0)
{
return (calc((len-1)/2+1)*power(2,(len-1)%2)-((len-1)%2==0))%mod*inv2%mod*3%mod+1;
}
else
{
return calc((len+1)/2)+1;
}
}
m[(len-2*(step()-k+1)-(len%2==0))]=1;
id=(len-2*(step()-k+1)-(len%2==0));
return ask(len,k-1)+1;
}
else
{
if(len%2==0)
{
if(m[len-1-1])
{
m[len-1-1]=0;
if(len-1-1==id)
{
id=-1;
}
return (ask(len-1,k)+calc((len-1)/2+1)*power(2,(len-1)%2))%mod;
}
else
{
return (ask(len-1,k)+calc((len-1)/2+1)*power(2,(len-1)%2)*inv2%mod*3%mod)%mod;
}
}
return (ask(len-1,k)+calc((len-1)/2+1)*power(2,(len-1)%2))%mod;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int k;
cin>>s>>t>>k;
reverse(s.begin(),s.end());
reverse(t.begin(),t.end());
id=-1;
for(int i=max(s.size(),t.size())-1;i>=0;i--)
{
if(i<s.size())
{
m[i]=m[i]^(s[i]-'0');
}
if(i<t.size())
{
m[i]=m[i]^(t[i]-'0');
}
if(m[i])
{
id=i;
}
}
if(id==-1)
{
cout<<calc(k)-1<<"\n";
}
else if(k>step())
{
cout<<-1<<"\n";
}
else
{
cout<<ask(max(s.size(),t.size()),k)-1<<"\n";
}
for(int i=max(s.size(),t.size())-1;i>=0;i--)
{
m[i]=0;
}
}
return 0;
}