Submission #1193214

#TimeUsernameProblemLanguageResultExecution timeMemory
1193214DobromirAngelovCrossing (JOI21_crossing)C++20
100 / 100
251 ms23832 KiB
#include<bits/stdc++.h> #define endl '\n' using namespace std; const int MAXN=2e5+5; const int B=137; const int MOD=1e9+7; int n,q; vector<vector<int> > v; vector<int> hashes; vector<int> a; long long bpw[MAXN]; long long oneH[MAXN]; void precomp() { bpw[0]=1; for(int i=1;i<=n;i++) bpw[i]=bpw[i-1]*B%MOD; oneH[0]=0; for(int i=1;i<=n;i++) oneH[i]=(oneH[i-1]+bpw[i-1])%MOD; } struct SegmentTree { struct Node { long long h; int len; Node() {}; Node(long long _h,int _len) { h=_h; len=_len; } }; Node tree[4*MAXN]; int lazy[4*MAXN]; void init() { fill(tree,tree+4*n+1,Node(0,0)); } Node combine(Node x,Node y) { int h=(x.h*bpw[y.len]+y.h)%MOD; int len=x.len+y.len; return Node(h,len); } void build(int node,int l,int r) { if(l==r) { tree[node].h=a[l]; tree[node].len=1; return; } int mid=(l+r)/2; build(2*node,l,mid); build(2*node+1,mid+1,r); tree[node]=combine(tree[2*node], tree[2*node+1]); } int calcOneHash(int val,int len) { return oneH[len]*val%MOD; } void push(int node,int l,int r) { if(lazy[node]==0) return; if(l!=r) { tree[2*node].h=calcOneHash(lazy[node],tree[2*node].len); tree[2*node+1].h=calcOneHash(lazy[node],tree[2*node+1].len); lazy[2*node]=lazy[2*node+1]=lazy[node]; } lazy[node]=0; } void update(int node,int l,int r,int ql,int qr,int val) { if(ql<=l && r<=qr) { tree[node].h=calcOneHash(val, tree[node].len); lazy[node]=val; return; } push(node,l,r); int mid=(l+r)/2; if(ql<=mid) update(2*node,l,mid,ql,qr,val); if(mid<qr) update(2*node+1,mid+1,r,ql,qr,val); tree[node]=combine(tree[2*node], tree[2*node+1]); } }; SegmentTree tree; int getHash(vector<int> a) { long long ret=0; for(auto x: a) { ret=(ret*B+x)%MOD; } return ret; } int val(char c) { if(c=='O') return 1; if(c=='I') return 2; else return 3; } vector<int> toArr(string s) { vector<int> ret(s.size()); for(int i=0;i<s.size();i++) ret[i]=val(s[i]); return ret; } vector<int> cross(vector<int> a,vector<int> b) { vector<int> ret(a.size()); for(int i=0;i<a.size();i++) { if(a[i]==b[i]) ret[i]=a[i]; else ret[i]=6-a[i]-b[i]; } return ret; } bool eq(vector<int> a,vector<int> b) { for(int i=0;i<a.size();i++) if(a[i]!=b[i]) return 0; return 1; } string query() { int cur=tree.tree[1].h; for(auto x: hashes) { if(x==cur) return "Yes"; } return "No"; } int main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin>>n; for(int i=0;i<3;i++) { string s; cin>>s; vector<int> cur=toArr(s); if(v.empty()) v.push_back(cur); else { bool fl=0; for(auto x: v) { if(eq(x,cur)) fl=1; } if(!fl) v.push_back(cur); } } for(int i=0;i<v.size();i++) { for(int j=i+1;j<v.size();j++) { vector<int> cur=cross(v[i],v[j]); bool fl=0; for(auto x: v) { if(eq(x,cur)) fl=1; } if(!fl) v.push_back(cur); } } precomp(); for(auto x: v) { hashes.push_back(getHash(x)); } cin>>q; string s; cin>>s; a=toArr(s); tree.build(1,0,n-1); cout<<query()<<endl; for(int i=0;i<q;i++) { int l,r; char c; cin>>l>>r>>c; l--; r--; tree.update(1,0,n-1,l,r,val(c)); cout<<query()<<endl; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...