1 条题解
-
0
首先手玩样例,发现怎么做资源库最多都只有九个。
如何证明?我们把
J,O,I分别设为0,1,2,容易得到每一位上 与 变换后即为 ,这样的转换显然只有 $x,y,z,x\textrm{ cross }y,y\textrm{ cross }z,z\textrm{ cross }x,x\textrm{ cross }(y\textrm{ cross }z),y\textrm{ cross }(z\textrm{ cross }x),z\textrm{ cross }(x\textrm{ cross }y)$。于是我们可以一开始把这九个字符串哈希出来,之后给出的字符串用线段树维护哈希值,判断是否与前面的九个值相等即可。
#include<iostream> #include<cstdio> #include<unordered_map> #define int long long using namespace std; const int mod=1000000007,mod2=998244353; struct node{ int sum1,sum2,lz; }tr[800005]; int n,q,v[1145],f[200005],pre[200005],f2[200005],pre2[200005]; string str[15],s; unordered_map<int,int>mp,mp2; string cr(string x,string y){ string z=""; for(int i=0;i<n;i++){ int w=v[x[i]],u=v[y[i]]; int k=(3-(w+u)%3)%3; if(k==0) z+="J"; else if(k==1) z+="O"; else z+="I"; } return z; } int gethash(string x){ int sum=0; for(int i=0;i<n;i++) sum=sum+(v[x[i]]+1)*f[i]%mod,sum%=mod; return sum; } int gethash2(string x){ int sum=0; for(int i=0;i<n;i++) sum=sum+(v[x[i]]+1)*f2[i]%mod2,sum%=mod2; return sum; } void pushup(int k,int l,int r,int mid){ tr[k].sum1=tr[k*2].sum1+tr[k*2+1].sum1*f[mid-l+1]%mod;tr[k].sum1%=mod; tr[k].sum2=tr[k*2].sum2+tr[k*2+1].sum2*f2[mid-l+1]%mod2;tr[k].sum2%=mod2; } void pushdown(int k,int l,int r,int mid){ if(tr[k].lz){ tr[k*2].sum1=pre[mid-l]*tr[k].lz%mod;tr[k*2].lz=tr[k].lz; tr[k*2+1].sum1=pre[r-mid-1]*tr[k].lz%mod;tr[k*2+1].lz=tr[k].lz; tr[k*2].sum2=pre2[mid-l]*tr[k].lz%mod2;tr[k*2].lz=tr[k].lz; tr[k*2+1].sum2=pre2[r-mid-1]*tr[k].lz%mod2;tr[k*2+1].lz=tr[k].lz; tr[k].lz=0; } } void build(int k,int l,int r){ if(l==r){ tr[k].sum1=v[s[l]]+1; tr[k].sum2=v[s[l]]+1; return; } int mid=(l+r)/2; build(k*2,l,mid);build(k*2+1,mid+1,r); pushup(k,l,r,mid); } void update(int k,int l,int r,int x,int y,int op){ if(r<x||l>y) return; if(x<=l&&r<=y){ tr[k].sum1=pre[r-l+1-1]*op%mod; tr[k].sum2=pre2[r-l+1-1]*op%mod2; tr[k].lz=op; return; } int mid=(l+r)/2; pushdown(k,l,r,mid); update(k*2,l,mid,x,y,op); update(k*2+1,mid+1,r,x,y,op); pushup(k,l,r,mid); } signed main(){ cin>>n>>str[1]>>str[2]>>str[3];v['J']=0,v['O']=1,v['I']=2; f[0]=1;for(int i=1;i<=n;i++) f[i]=f[i-1]*233%mod; for(int i=0;i<=n;i++) pre[i]=f[i]+pre[i-1],pre[i]%=mod; f2[0]=1;for(int i=1;i<=n;i++) f2[i]=f2[i-1]*131%mod2; for(int i=0;i<=n;i++) pre2[i]=f2[i]+pre2[i-1],pre2[i]%=mod2; str[4]=cr(str[1],str[2]);str[5]=cr(str[2],str[3]);str[6]=cr(str[3],str[1]); str[7]=cr(str[4],str[5]);str[8]=cr(str[5],str[6]);str[9]=cr(str[6],str[4]); for(int i=1;i<=9;i++) mp[gethash(str[i])]++,mp2[gethash2(str[i])]++/*,cout<<str[i]<<' '<<gethash(str[i])<<endl*/; cin>>q>>s;s=" "+s; build(1,1,n); // cout<<tr[1].sum<<endl; if(mp.count(tr[1].sum1)&&mp2.count(tr[1].sum2)) cout<<"Yes\n"; else cout<<"No\n"; while(q--){ int l,r,x;char op; cin>>l>>r>>op; x=v[op]+1;update(1,1,n,l,r,x); // cout<<tr[1].sum<<endl; if(mp.count(tr[1].sum1)&&mp2.count(tr[1].sum2)) cout<<"Yes\n"; else cout<<"No\n"; } return 0; }
- 1
信息
- ID
- 10163
- 时间
- 5000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者