2026.10.05总结
认证学习乱搞字符串HASH
题单地址
主要是进制位hash,形成双hash+ull自然溢出的写法
base:233,911,131;
mod:1e9+7,1e7+9,13697891,998244353;
用正、反hash \(O(1)\) 比较,\(O(LEN)\)预处理。
区间hash:
hash=hs[r]-hs[l-1]*sum[r-l+1];//sum预处理进制位
异或hash
inline ull clhs(string & ss){
ull cnt=0;
for(int i=1;i<=n;i++){
cnt^=w[i][joi(ss[i])];
}
return cnt;
}
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
for(int i=1;i<=n;i++){
for(int c=0;c<=2;c++){
w[i][c]=rng();
prw[i][c]=prw[i-1][c]^w[i][c];
}
}
ODT+异或hash
#include <bits/stdc++.h>
using namespace std;
#define puu pair<unsigned long long,unsigned long long>
#define ull unsigned long long
#define ll long long
#define bs1 233
#define bs2 911
#define mod1 13697891
#define mod2 1e9+7
#define fi first
#define se second
const int N=2e5+10;
int n,tot;
string sa,sb,sc;
string s[20],t;
ull w[N][3],prw[N][3];
ull hs[15];
ull now;
map<int,pair<int,int>>odt;
map<ull,int>mp;
inline int joi(char c){
if(c=='J')return 0;
if(c=='O')return 1;
return 2;
}
inline char ioj(int a){
if(a==0)return 'J';
if(a==1)return 'O';
return 'I';
}
inline void cross(string s1,string s2,string & ss){
ss.resize(n+2);
int qwq,pwp;
for(int i=1;i<=n;i++){
qwq=joi(s1[i]);
pwp=joi(s2[i]);
qwq=(6-pwp-qwq)%3;
ss[i]=ioj(qwq);
}
return ;
}
inline ull clhs(string & ss){
ull cnt=0;
for(int i=1;i<=n;i++){
cnt^=w[i][joi(ss[i])];
}
return cnt;
}
inline auto split(int pos){
auto it=odt.lower_bound(pos);
if(it!=odt.end()&&it->fi==pos)return it;
--it;
int l=it->fi,r=it->se.fi,c=it->se.se;
odt[l]={pos-1,c};
return odt.insert({pos,{r,c}}).fi;
}
inline void assign(int l,int r,int c){
auto itr=split(r+1),itl=split(l);
int L,R,cc;
for(auto it=itl;it!=itr;it++){
L=it->fi,R=it->se.fi,cc=it->se.se;
now^=prw[R][cc]^prw[L-1][cc];
}
odt.erase(itl,itr);
auto it=odt.insert({l,{r,c}}).fi;
now^=prw[r][c]^prw[l-1][c];
auto nxt=next(it);
if(nxt!=odt.end()&&nxt->se.se==c){
it->se.fi=nxt->se.fi;
odt.erase(nxt);
}
if(it!=odt.begin()){
auto prv=prev(it);
if(prv->se.se==c){
prv->se.fi=it->se.fi;
odt.erase(it);
}
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
cin>>sa>>sb>>sc;
s[1]=" "+sa;
s[2]=" "+sb;
s[3]=" "+sc;
cross(s[1],s[2],s[4]);
cross(s[2],s[3],s[5]);
cross(s[3],s[1],s[6]);
cross(s[4],s[5],s[7]);
cross(s[5],s[6],s[8]);
cross(s[6],s[4],s[9]);
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
for(int i=1;i<=n;i++){
for(int c=0;c<=2;c++){
w[i][c]=rng();
prw[i][c]=prw[i-1][c]^w[i][c];
}
}
for(int k=1;k<=9;k++){
mp[clhs(s[k])]=1;
}
int q;
cin>>q;
cin>>t;
t=' '+t;
now=clhs(t);
if(mp.count(now)){
cout<<"Yes\n";
}
else cout<<"No\n";
for(int i=1,st=1;i<=n+1;i++){
if(i==n+1||t[i]!=t[st]){
odt[st]={i-1,joi(t[st])};
st=i;
}
}
odt[n+1]={n+1,-1};
int l,r;
char c;
for(int i=1;i<=q;i++){
cin>>l>>r>>c;
assign(l,r,joi(c));
cout<<(mp.count(now)?"Yes":"No")<<'\n';
}
return 0;
}

浙公网安备 33010602011771号