L.Let's Swap 找规律+字符串双哈希
作者:互联网
(这道题赛后补的,就是说现场根本没有时间开到www
依据题意,有两种操作,过程还蛮复杂的,又倒置又反转,然后我看到这种操作一般就懵逼了,然后捏?
这时候一般就需要手%啥的,就是画图模拟,找规律,一般都有一些”性质“的
比如这题的一些性质:
#同一个操作使用两次,会撤销,相当于没有操作
那么..设想操作A,B组成了一个序列,这个序列只能是:
ABABABA....
BABABAB....
#那么AB操作,实质上是什么呐?
画图可知,一次ab或者ba,相当于把字符串向左或者向右移动 abs(L1-L2),若干次操作ab(ba),相当于把字符串向左或者向右移动若干次
题解在这边写的是d=gcd(s.length(),L1-L2),最多位移n/d次,在这边看了好久,自己推了一下应该是因为:
那么我们就可以判断T是否是S经过若干次位移得到的——用kmp或者字符串哈希
kmp(这玩意学一次忘一次,每次用到都得重新学x,干脆写Hash:
字符串Hash的思想要是不明白的话左转某谷或者某dn哇~
想记录一下实现的细节:
比如要把T扩展成2倍,因为我们肯定要涉及到末尾取一部分+前面的一部分合并起来,展开成两倍可以实现
然后循环n次(最多位移n次吧,不过这个应该是为了保证不错,有往上放大过的数值了),判断Hash值相等不相等~
又因为有B(AB)(AB)(AB)
或者A(AB)(AB)(AB)
或者(AB)(AB)S
三种情况分别试一下
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+7; const long long mod=1e9+7; string s,t,tmp; long long ss[maxn],ss1[maxn],tt[maxn],tt1[maxn],p[maxn],p1[maxn]; int len,totlen,l1,l2; bool check( ) { for(int i=0;i<totlen;i++){ ss[i+1]=(ss[i]*31%mod+(tmp[i]-'a'+1)%mod+mod)%mod; ss1[i+1]=(ss1[i]*29%mod+(tmp[i]-'a'+1)%mod+mod)%mod; } //double hash int cnt=totlen,pos=totlen,flag=0; //最多移位n次,这里有点暴力枚举了 while(cnt){ pos%=2*totlen; while(pos<totlen) pos+=len; if((tt[pos]-tt[pos-totlen]*p[totlen]%mod+mod)%mod==ss[totlen]&& (tt1[pos]-tt1[pos-totlen]*p1[totlen]%mod+mod)%mod==ss1[totlen]) { flag=1;break; } pos+=len; cnt--; } return flag; } void solve(){ //ababab,delta=gcd(l1-l2) totlen=s.length(); len=abs(l1-l2); t=t+t; for(int i=0;i<2*totlen;i++){ tt[i+1]=(tt[i]*31%mod+(t[i]-'a'+1)%mod+mod)%mod; tt1[i+1]=(tt1[i]*29%mod+(t[i]-'a'+1)%mod+mod)%mod; } tmp=s; if( check() ) { cout<<"yes"<<endl; return; } tmp=s.substr(l1)+s.substr(0,l1); reverse(tmp.begin(),tmp.end()); if( check() ) { cout<<"yes"<<endl; return; } tmp=s.substr(l2)+s.substr(0,l2); reverse(tmp.begin(),tmp.end()); if( check() ) { cout<<"yes"<<endl; return; } cout<<"no"<<endl; return; } int main() { //freopen("lys.in","r",stdin); p[0]=1;p1[0]=1; for(int i=1;i<maxn-2;i++) { p[i]=p[i-1]*31%mod;p1[i]=p1[i-1]*29%mod; } int q; cin>>q; while(q--){ cin>>s; cin>>t; cin>>l1>>l2; solve(); } }
标签:AB,或者,long,maxn,Swap,哈希,操作,字符串,Let 来源: https://www.cnblogs.com/liyishui2003/p/16478973.html