This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define INF 10000000
#define MOD 1000000007
#define MID ((l+r)/2)
#define HASHMOD 2305843009213693951
#define ll long long
#define ull unsigned long long
#define F first
#define S second
typedef pair<ll, ll> ii;
typedef pair<ii, int> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef map<int, int> mii;
#define EPS 1e-6
#define FOR(i,n) for(int i=0;i<((int)(n));i++)
#define FORi(i,a,b) for(int i=((int)(a));i<((int)(b));i++)
#define FOA(v, a) for(auto v : a)
int t, n;
vi a, b;
#define Q 4
#define enumer(x) (x=='I' ? 1 : (x=='J' ? 2 : 3))
string cross(string a, string b){
FOR(i,a.size()){
if(a[i]==b[i]) continue;
if(a[i]+b[i]=='O'+'I') a[i] = 'J';
else if(a[i]+b[i]=='J'+'I') a[i] = 'O';
else if(a[i]+b[i]=='O'+'J') a[i] = 'I';
}
return a;
}
ll mpow(ll a, ll b, ll m){
if(b==0) return 1;
if(b==1) return a;
ll z = mpow(a, b/2, m);
z*=z;
z%=m;
if(b%2) z*=a;
return z%m;
}
ll inv(ll x, ll m){
return mpow(x, m-2, m);
}
#define NMOD 1
ll invx[NMOD];
ll mods[NMOD] = {MOD+200};
template<typename T>
struct seg_tree{
struct node{
vector<T> val;
T laz;
int left=-1;
int right=-1;
node() {val.assign(NMOD, 0); laz=0, left=-1, right=-1;}
node(T v){ val.assign(NMOD, v);}
};
vector<node> seg;
static inline int N;
const int RAND_VALUE=0;
seg_tree(int n){N=n, seg.assign(1, node());}
inline node merge(node par, node a, node b, int l, int r){
node ret;
ret.left = par.left, ret.right = par.right;
FOR(m,NMOD) ret.val[m] = ((a.val[m] * mpow(Q, r-MID, mods[m]))%mods[m] + b.val[m])%mods[m];
return ret;
}
inline void update_node(int ind, int val, int l, int r){
FOR(m,NMOD){
seg[ind].val[m] = (val * (mpow(Q, (r-l+1), mods[m])-1) * invx[m])%mods[m];
}
seg[ind].laz = val;
}
inline void down(node &par, int l, int r){
if(par.laz){
FOR(m,NMOD){
seg[par.left].val[m] = (((par.laz * (mpow(Q, (MID-l+1), mods[m])-1))%mods[m]) * invx[m])%mods[m];
seg[par.right].val[m] = (((par.laz * (mpow(Q, (r-MID), mods[m])-1))%mods[m]) * invx[m])%mods[m];
}
seg[par.left].laz = par.laz;
seg[par.right].laz = par.laz;
}
par.laz = 0;
}
inline void create_children(int ind){
node par = seg[ind];
if(par.left==-1) par.left=seg.size(), seg.push_back(node());
if(par.right==-1) par.right=seg.size(), seg.push_back(node());
seg[ind] = par;
}
void build(vector<T>& arr, int l=0, int r=N-1, int ind=0){
if(l==r) seg[ind] = node(arr[l]);
else{
create_children(ind);
build(arr,l,MID,seg[ind].left);
build(arr,MID+1,r,seg[ind].right);
seg[ind] = merge(seg[ind], seg[seg[ind].left], seg[seg[ind].right], l,r);
}
}
void update(int rl, int rr, int val, int l=0, int r=N-1, int ind=0){
if(rl<=l && r<=rr) update_node(ind, val,l,r);
else if(rr<l || r<rl) return;
else{
create_children(ind);
down(seg[ind],l,r);
update(rl,rr,val,l,MID,seg[ind].left);
update(rl,rr,val,MID+1,r,seg[ind].right);
seg[ind] = merge(seg[ind], seg[seg[ind].left], seg[seg[ind].right], l,r);
}
}
node _query(int rl, int rr, int l=0, int r=N-1, int ind=0){
if(rl<=l && r<=rr) return seg[ind];
else if(rl>r || l>rr) return node(RAND_VALUE);
else{
create_children(ind);
down(seg[ind],l,r);
return merge(seg[ind], _query(rl, rr, l, MID, seg[ind].left), _query(rl,rr,MID+1,r,seg[ind].right), l, r);
}
}
vector<T> query(int l, int r){
return _query(l,r).val;
}
};
vector<ll> hsh(string s){
vector<ll> a;
FOR(m, NMOD){
ll x = 0;
FOA(v, s){
x*=Q;
x+=enumer(v);
x%=mods[m];
}
a.push_back(x);
}
return a;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
FOR(i, NMOD) invx[i] = inv(Q-1, mods[i]);
int n;
cin>>n;
string s[3];
cin>>s[0]>>s[1]>>s[2];
set<string> all;
set<vector<ll> > hshs;
int p=0;
hshs.insert(hsh(s[0]));
hshs.insert(hsh(s[1]));
hshs.insert(hsh(s[2]));
all.insert(s[0]);
all.insert(s[1]);
all.insert(s[2]);
while(p!=(int)all.size()){
p = all.size();
FOA(a, all){
FOA(b, all){
if(a==b) continue;
hshs.insert(hsh(cross(a,b)));
all.insert(cross(a,b));
}
}
}
//FOA(v, all) cout<<v<<" "<<hsh(v)<<endl;
seg_tree<ll> seg(n);
int q;
cin>>q;
string t;
cin>>t;
vector<ll> b(n);
FOR(i,n) b[i] = enumer(t[i]);
seg.build(b);
do{
//cout<<seg.query(0, n-1)<<endl;
if(hshs.count(seg.query(0, n-1))) cout<<"Yes\n";
else cout<<"No\n";
if(q==0) break;
int l, r;
char c;
cin>>l>>r>>c;
seg.update(l-1, r-1, enumer(c));
}while(q--);
}
Compilation message (stderr)
Main.cpp:69:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
69 | static inline int N;
| ^~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |