Problem:
問題文
実数変数 $X_1, X_2, ...$ があり、何らかの初期値が割り振られている。
これから $Q$ 個の情報が順番に与えられる。与えられる情報は以下の2種類のいずれかである。
min $\{X_{a_i}, X_{a_i+1}, ..., X_{b_i}\} = y_i$ である。
変数 $X_{a_i}, X_{a_i+1}, ..., X_{b_i}$ に $y_i$ を代入する。
これら $Q$ 個の情報が矛盾しないように各変数の初期値を選べるかどうか判定せよ。
入力
入力は以下の形式に従う。与えられる数は全て整数である。
$Q$
$t_1$ $a_1$ $b_1$ $y_1$
$t_2$ $a_2$ $b_2$ $y_2$
$...$
$t_Q$ $a_Q$ $b_Q$ $y_Q$
$t_i=0$ のとき、min$\{X_{a_i}, X_{a_i+1}, ..., X_{b_i}\} = y_i$ であることを示している。
$t_i=1$ のとき、$X_{a_i}, X_{a_i+1}, ..., X_{b_i}$ に $y_i$ を代入することを示している。
制約
$1 \leq Q \leq 5 \times 10^4$
$0 \leq t_i \leq 1$
$1 \leq a_i \leq b_i \leq 10^9$
$1 \leq y_i \leq 10^9$
出力
全ての情報が矛盾しないような初期値が存在すれば"YES"を、そうでなければ"NO"を1行に出力せよ。
Sample Input 1
5
0 1 2 8
0 2 3 9
0 2 2 11
1 2 2 7
0 1 3 7
Output for the Sample Input 1
YES
初期値を、$\{X_1, X_2, X_3\} = \{8, 11, 9\}$ とする。このとき、
min$\{X_1, X_2\} = $min$\{8, 11\} = 8$
min$\{X_2, X_3\} = $min$\{11, 9\} = 9$
min$\{X_2\} =  $min$\{11\} = 11$
$X_2 = 7$
min$\{X_1, X_2, X_3\} = $min$\{8, 7, 9\} = 7$
となり全ての情報と矛盾しない。
Sample Input 2
2
1 10 100 333
0 100 1000 555
Output for the Sample Input 2
NO
1つ目の情報で $X_{10}$ から $X_{100}$ の値が $333$ になったことが分かる。
2つ目の情報は min$\{X_{100},...,X_{1000}\}=555$ となることを示しているが、これは $X_{100}=333$ であることから矛盾が生じる。

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstdlib>
#include <set>
#include <algorithm>
using namespace std;
#define N (1<<18)

struct Query{
	int t,a,b,y;
};
int Q;
Query que[50000];

set<int> next;

int dead[50000];
vector< pair<int,int> > event[200010];

struct Node{
	int minimum;
	int lazy;
	Node(){ minimum = lazy = 0; }
};

Node seg[2*N];


vector<int> u;
int n;

void update(int l,int r,int v,int k=1,int a=1,int b=N){
	if( seg[k].lazy && k < N ){
		seg[k*2].minimum = seg[k].lazy;
		seg[k*2+1].minimum = seg[k].lazy;
		seg[k*2].lazy = seg[k].lazy;
		seg[k*2+1].lazy = seg[k].lazy;
	}
	seg[k].lazy = 0;
	if( b < l || r < a ) return;
	
	if( l <= a && b <= r ){
		seg[k].minimum = v;
		seg[k].lazy = v;
		return;
	}
	int m = (a+b)>>1;
	update(l,r,v,k*2,a,m);
	update(l,r,v,k*2+1,m+1,b);
	seg[k].minimum = min( seg[k*2].minimum , seg[k*2+1].minimum );
}

int get(int l,int r,int k=1,int a=1,int b=N){
	if( seg[k].lazy && k < N ){
		seg[k*2].minimum = seg[k].lazy;
		seg[k*2+1].minimum = seg[k].lazy;
		seg[k*2].lazy = seg[k].lazy;
		seg[k*2+1].lazy = seg[k].lazy;
	}
	seg[k].lazy = 0;
	if( b < l || r < a ) return 2e9;
	
	if( l <= a && b <= r ){
		return seg[k].minimum;
	}
	int m = (a+b)>>1;
	int vl = get(l,r,k*2,a,m);
	int vr = get(l,r,k*2+1,m+1,b);
	seg[k].minimum = min( seg[k*2].minimum , seg[k*2+1].minimum );
	return min(vl,vr);
}

int seg2[2*N];


void update2(int l,int r,int v,int k=1,int a=1,int b=N){
	if( b < l || r < a ) return;
	
	if( l <= a && b <= r ){
		seg2[k] = max(seg2[k],v);
		return;
	}
	int m = (a+b)>>1;
	update2(l,r,v,k*2,a,m);
	update2(l,r,v,k*2+1,m+1,b);
}


int get2(int i){
	i += N - 1;
	int ans = 0;
	while(i){
		ans = max( ans , seg2[i]);
		i /= 2;
	}
	return ans;
}

int main(){
	scanf("%d",&Q);
	for(int i = 0 ; i < Q ; i++){
		scanf("%d%d%d%d",&que[i].t,&que[i].a,&que[i].b,&que[i].y);
	}
	
	for(int i = 0 ; i < Q ; i++){
		u.push_back(que[i].a);
		u.push_back(que[i].a+1);
		
		u.push_back(que[i].b);
		u.push_back(que[i].b+1);
	}
	u.push_back(0);
	sort(u.begin(),u.end());
	u.erase(unique(u.begin(),u.end()),u.end());
	n = u.size();
	for(int i = 0 ; i < Q ; i++){
		que[i].a = lower_bound(u.begin(),u.end(),que[i].a) - u.begin();
		que[i].b = lower_bound(u.begin(),u.end(),que[i].b) - u.begin();
	}
	
	for(int i = 1 ; i < n ; i++) next.insert(i);
	
	vector<int> arr(n);
	for(int i = 0 ; i < Q ; i++){
		if( que[i].t == 0 ){
			update2(que[i].a,que[i].b,que[i].y);
		}else{
			set<int>::iterator it = next.lower_bound(que[i].a);
			while(it != next.end()){
				if( *it > que[i].b ) break;
				arr[*it] = get2(*it);
				next.erase(it++);
			}
		}
	}
	for(set<int>::iterator it = next.begin(); it != next.end(); ++it){
		arr[*it] = get2(*it);
	}
	
	
	for(int i = 1 ; i < n ; i++) update(i,i,arr[i]);
	//for(int i = 1 ; i < n ; i++) cout << arr[i] << " "; cout << endl;
	for(int i = 0 ; i < Q ; i++){
		if( que[i].t == 0 ){
			if( que[i].y != get(que[i].a,que[i].b) ){	
				cout << "NO" << endl;
				return 0;
			}
		}else{
			update(que[i].a,que[i].b,que[i].y);
		}
	}
	cout << "YES" << endl;
}
accuracy: 1
time_ms: 110
memory_kb: 24568
final_rank: 10

code_snippet: #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2359"

#include<bits/stdc++.h>
using namespace std;

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T> void drop(const T &x){cout<<x<<endl;exit(0);}
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif


#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;
#endif

//BEGIN CUT HERE
template<typename V>
V compress(V vs){
  sort(vs.begin(),vs.end());
  vs.erase(unique(vs.begin(),vs.end()),vs.end());
  return vs;
}
template<typename T>
map<T, int> dict(const vector<T> &vs){
  map<T, int> res;
  for(int i=0;i<(int)vs.size();i++)
    res[vs[i]]=i;
  return res;
}
map<char, int> dict(const string &s){
  return dict(vector<char>(s.begin(),s.end()));
}
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif


#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;
#endif

//BEGIN CUT HERE
template<typename T, typename ...Ts>
vector<T> fusion(vector<T> bs,Ts... ts){
  auto append=[&](auto vs){for(auto v:vs) bs.emplace_back(v);};
  initializer_list<int>{(void(append(ts)),0)...};
  return bs;
}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif


#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;

#endif
//BEGIN CUT HERE
template<typename T>
vector<T> shift(vector<T> vs,vector<T> as){
  assert(vs.size()==as.size());
  for(int i=0;i<(int)vs.size();i++) vs[i]+=as[i];
  return vs;
}
template<typename T>
vector<T> shift(vector<T> vs,T a){
  return shift(vs,vector<T>(vs.size(),a));
}

template<typename T, typename ...Ts>
vector<T> near(vector<T> vs,Ts... ts){
  vector<T> rs;
  rs.reserve(vs.size()*sizeof...(ts));
  auto append=[&](auto a){
    auto ws=shift(vs,a);
    for(auto w:ws) rs.emplace_back(w);
  };
  initializer_list<int>{(void(append(ts)),0)...};
  return rs;
}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template <typename E>
struct SegmentTree{
  using H = function<E(E,E)>;
  int n,height;
  H h;
  E ei;
  vector<E> laz;

  SegmentTree(H h,E ei):h(h),ei(ei){}

  void init(int n_){
    n=1;height=0;
    while(n<n_) n<<=1,height++;
    laz.assign(2*n,ei);
  }

  inline void propagate(int k){
    if(laz[k]==ei) return;
    laz[(k<<1)|0]=h(laz[(k<<1)|0],laz[k]);
    laz[(k<<1)|1]=h(laz[(k<<1)|1],laz[k]);
    laz[k]=ei;
  }

  inline void thrust(int k){
    for(int i=height;i;i--) propagate(k>>i);
  }

  void update(int a,int b,E x){
    if(a>=b) return;
    thrust(a+=n);
    thrust(b+=n-1);
    for(int l=a,r=b+1;l<r;l>>=1,r>>=1){
      if(l&1) laz[l]=h(laz[l],x),l++;
      if(r&1) --r,laz[r]=h(laz[r],x);
    }
  }

  E get_val(int a){
    thrust(a+=n);
    return laz[a];
  }

  void set_val(int a,E x){
    thrust(a+=n);
    laz[a]=x;
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#define SegmentTree SegmentTree2
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template <typename T,typename E>
struct SegmentTree{
  using F = function<T(T,T)>;
  using G = function<T(T,E)>;
  using H = function<E(E,E)>;
  int n,height;
  F f;
  G g;
  H h;
  T ti;
  E ei;
  vector<T> dat;
  vector<E> laz;
  SegmentTree(F f,G g,H h,T ti,E ei):
    f(f),g(g),h(h),ti(ti),ei(ei){}

  void init(int n_){
    n=1;height=0;
    while(n<n_) n<<=1,height++;
    dat.assign(2*n,ti);
    laz.assign(2*n,ei);
  }

  void build(const vector<T> &v){
    int n_=v.size();
    init(n_);
    for(int i=0;i<n_;i++) dat[n+i]=v[i];
    for(int i=n-1;i;i--)
      dat[i]=f(dat[(i<<1)|0],dat[(i<<1)|1]);
  }

  inline T reflect(int k){
    return laz[k]==ei?dat[k]:g(dat[k],laz[k]);
  }

  inline void propagate(int k){
    if(laz[k]==ei) return;
    laz[(k<<1)|0]=h(laz[(k<<1)|0],laz[k]);
    laz[(k<<1)|1]=h(laz[(k<<1)|1],laz[k]);
    dat[k]=reflect(k);
    laz[k]=ei;
  }

  inline void thrust(int k){
    for(int i=height;i;i--) propagate(k>>i);
  }

  inline void recalc(int k){
    while(k>>=1)
      dat[k]=f(reflect((k<<1)|0),reflect((k<<1)|1));
  }

  void update(int a,int b,E x){
    if(a>=b) return;
    thrust(a+=n);
    thrust(b+=n-1);
    for(int l=a,r=b+1;l<r;l>>=1,r>>=1){
      if(l&1) laz[l]=h(laz[l],x),l++;
      if(r&1) --r,laz[r]=h(laz[r],x);
    }
    recalc(a);
    recalc(b);
  }

  void set_val(int a,T x){
    thrust(a+=n);
    dat[a]=x;laz[a]=ei;
    recalc(a);
  }

  T query(int a,int b){
    if(a>=b) return ti;
    thrust(a+=n);
    thrust(b+=n-1);
    T vl=ti,vr=ti;
    for(int l=a,r=b+1;l<r;l>>=1,r>>=1) {
      if(l&1) vl=f(vl,reflect(l++));
      if(r&1) vr=f(reflect(--r),vr);
    }
    return f(vl,vr);
  }

  template<typename C>
  int find(int st,C &check,T &acc,int k,int l,int r){
    if(l+1==r){
      acc=f(acc,reflect(k));
      return check(acc)?k-n:-1;
    }
    propagate(k);
    int m=(l+r)>>1;
    if(m<=st) return find(st,check,acc,(k<<1)|1,m,r);
    if(st<=l&&!check(f(acc,dat[k]))){
      acc=f(acc,dat[k]);
      return -1;
    }
    int vl=find(st,check,acc,(k<<1)|0,l,m);
    if(~vl) return vl;
    return find(st,check,acc,(k<<1)|1,m,r);
  }

  template<typename C>
  int find(int st,C &check){
    T acc=ti;
    return find(st,check,acc,1,0,n);
  }
};
//END CUT HERE
#ifndef call_from_test

signed CFR569_C(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m;
  cin>>n>>m;
  vector<int> as(n),bs(m);
  for(int i=0;i<n;i++) cin>>as[i];
  for(int i=0;i<m;i++) cin>>bs[i];

  auto f=[](int a,int b){return max(a,b);};
  auto g=[](int a,int b){return a+b;};
  int ti=0,ei=0;
  SegmentTree<int, int> seg(f,g,g,ti,ei);

  const int sz = 1<<20;
  seg.build(vector<int>(sz,0));

  for(int i=0;i<n;i++) seg.update(sz-as[i],sz,+1);
  for(int i=0;i<m;i++) seg.update(sz-bs[i],sz,-1);

  int q;
  cin>>q;
  auto check=[](int d){return d>0;};
  for(int i=0;i<q;i++){
    int t,k,v;
    cin>>t>>k>>v;
    k--;
    if(t==1){
      seg.update(sz-as[k],sz,-1);
      as[k]=v;
      seg.update(sz-as[k],sz,+1);
    }
    if(t==2){
      seg.update(sz-bs[k],sz,+1);
      bs[k]=v;
      seg.update(sz-bs[k],sz,-1);
    }
    int pos=seg.find(0,check);
    cout<<(pos<0?pos:sz-pos)<<"\n";
  }
  cout<<flush;
  return 0;
}
/*
  verified on 2019/10/28
  https://codeforces.com/contest/1179/problem/C
*/

signed main(){
  CFR569_C();
  return 0;
}
#endif

#undef SegmentTree
#undef call_from_test

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int q;
  cin>>q;
  vector<int> ts(q),as(q),bs(q),ys(q);
  for(int i=0;i<q;i++) cin>>ts[i]>>as[i]>>bs[i]>>ys[i];

  vector<int> vs=fusion(near(as,-1,0,1),near(bs,-1,0,1));
  vs.emplace_back(0);
  vs.emplace_back(1e9+10);
  vs=compress(vs);
  auto dc=dict(vs);
  int m=dc.size();

  using P = pair<int, int>;
  auto h=[&](P a,P b){
    if(a.first) return a;
    return P(b.first,max(a.second,b.second));
  };
  P ei(0,0);
  SegmentTree<P> seg(h,ei);
  seg.init(m);

  for(int i=0;i<q;i++){
    int l=dc[as[i]];
    int r=dc[bs[i]+1];

    if(ts[i]==0) seg.update(l,r,P(0,ys[i]));
    if(ts[i]==1) seg.update(l,r,P(1,0));
  }

  vector<int> zs(m);
  for(int i=0;i<m;i++) zs[i]=seg.get_val(i).second;

  auto ff=[&](int a,int b){return min(a,b);};
  auto gg=[&](int  ,int b){return b;};
  SegmentTree2<int, int> seg2(ff,gg,gg,INT_MAX,-1);
  seg2.build(zs);

  for(int i=0;i<q;i++){
    int l=dc[as[i]];
    int r=dc[bs[i]+1];
    if(ts[i]==0){
      if(seg2.query(l,r)!=ys[i]) drop("NO");
    }
    if(ts[i]==1){
      seg2.update(l,r,ys[i]);
    }
  }
  drop("YES");
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 36756
final_rank: 14

code_snippet: #include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <cassert>
#include <fstream>
#include <utility>
#include <functional>
#include <time.h>
#include <stack>
#define popcount __builtin_popcount
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;

template<typename Monoid, typename OperatorMonoid=Monoid>
struct LazySegmentTree{
	using F=function<Monoid(Monoid, Monoid)>;
	using G=function<Monoid(Monoid, OperatorMonoid, int)>;
	using H=function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
	int sz;
	vector<Monoid> data;
	vector<OperatorMonoid> lazy;
	const F f;
	const G g;
	const H h;
	const Monoid e1;
	const OperatorMonoid e0;

	LazySegmentTree(int n, const F f, const G g, const H h, const Monoid &e1, const OperatorMonoid &e0): f(f), g(g), h(h), e1(e1), e0(e0){
		sz=1;
		while(sz<n) sz<<=1;
		data.resize(2*sz-1, e1);
		lazy.resize(2*sz-1, e0);
	}

	void build(vector<Monoid> v){
		for(int i=0; i<v.size(); i++) data[i+sz-1]=v[i];
		for(int i=sz-2; i>=0; i--) data[i]=f(data[2*i+1], data[2*i+2]);
	}

	void eval(int k, int l, int r){
		if(lazy[k]!=e0){
			data[k]=g(data[k], lazy[k], r-l);
			if(k<sz-1){
				lazy[2*k+1]=h(lazy[2*k+1], lazy[k]);
				lazy[2*k+2]=h(lazy[2*k+2], lazy[k]);
			}
		}
		lazy[k]=e0;
	}

	void update(int a, int b, const OperatorMonoid &x, int k, int l, int r){
		eval(k, l, r);
		if(r<=a || b<=l) return;
		if(a<=l && r<=b){
			lazy[k]=h(lazy[k], x);
			eval(k, l, r);
		}else{
			update(a, b, x, 2*k+1, l, (l+r)/2);
			update(a, b, x, 2*k+2, (l+r)/2, r);
			data[k]=f(data[2*k+1], data[2*k+2]);
		}
	}
	void update(int a, int b, const OperatorMonoid &x){
		return update(a, b, x, 0, 0, sz);
	}

	Monoid find(int a, int b, int k, int l, int r){
		eval(k, l, r);
		if(b<=l || r<=a) return e1;
		if(a<=l && r<=b) return data[k];
		else return f(find(a, b, 2*k+1, l, (l+r)/2), find(a, b, 2*k+2, (l+r)/2, r));
	}
	Monoid find(int a, int b){
		return find(a, b, 0, 0, sz);
	}
	Monoid operator[](const int &k){
		return find(k, k+1);
	}
};
template<typename Monoid>
struct SegmentTree{
	using F=function<Monoid(Monoid, Monoid)>;
	int sz;
	vector<Monoid> seg;
	const F f;
	const Monoid e;

	SegmentTree(int n, const F f, const Monoid &e): f(f), e(e){
		sz=1;
		while(sz<n) sz<<=1;
		seg.resize(2*sz, e);
	}

	SegmentTree(int n, const F f, const Monoid &e, vector<Monoid> v): f(f), e(e){
		sz=1;
		while(sz<n) sz<<=1;
		seg.resize(2*sz, e);
		for(int i=0; i<n; i++) seg[i+sz]=v[i];
		for(int i=sz-1; i>=1; i--){
			seg[i]=f(seg[2*i], seg[2*i+1]);
		}
	}

	void update(int k, const Monoid &x){
		k+=sz;
		seg[k]=x;
		while(k>1){
			k>>=1;
			seg[k]=f(seg[2*k], seg[2*k+1]);
		}
	}

	Monoid query(int a, int b){
		a+=sz, b+=sz;
		Monoid ret=e;
		for(;a<b; a>>=1, b>>=1){
			if(b&1) ret=f(ret, seg[--b]);
			if(a&1) ret=f(ret, seg[a++]);
		}
		return ret;
	}

	Monoid operator[](const int &k) const{
		return seg[k+sz];
	}
};
int q;
int t[50050], a[50050], b[50050], y[50050];
int s[100010];
vector<int> upd;
vector<int> va[100010], vb[100010];
int main()
{
	scanf("%d", &q);
	vector<int> v;
	for(int i=0; i<q; i++){
		scanf("%d %d %d %d", &t[i], &a[i], &b[i], &y[i]);
		a[i]--;
		v.push_back(a[i]);
		v.push_back(b[i]);
	}
	sort(v.begin(), v.end());
	v.erase(unique(v.begin(), v.end()), v.end());
	int m=v.size();
	auto f=[](int a, int b){ return min(a, b);};
	auto g=[](int a, int x, int len){ return x;};
	auto h=[](int x, int y){ return y;};
	const int INF=1e9+7;
	LazySegmentTree<int> seg1(m, f, g, h, INF, INF);
	for(int i=q-1; i>=0; i--){
		a[i]=lower_bound(v.begin(), v.end(), a[i])-v.begin();
		b[i]=lower_bound(v.begin(), v.end(), b[i])-v.begin();
		if(t[i]==1) seg1.update(a[i], b[i], i);
	}
	for(int i=0; i<m; i++) s[i]=seg1[i];
	auto f2=[](int a, int b){ return max(a, b);};
	SegmentTree<int> seg2(q, f2, -1);
	for(int i=0; i<q; i++){
		if(t[i]==0){
			va[a[i]].push_back(i);
			vb[b[i]].push_back(i);
		}
	}
	upd.resize(m);
	for(int i=0; i<m; i++){
		for(auto x:va[i]){
			seg2.update(x, y[x]);
		}
		for(auto x:vb[i]){
			seg2.update(x, -1);
		}
		upd[i]=seg2.query(0, min(q, s[i]));
		if(upd[i]==-1) upd[i]=INF;
	}
	LazySegmentTree<int> seg(m, f, g, h, INF, INF);
	seg.build(upd);
	for(int i=0; i<q; i++){
		if(t[i]==1) seg.update(a[i], b[i], y[i]);
		else if(seg.find(a[i], b[i])!=y[i]){
			cout<<"NO"<<endl;
			return 0;
		}
	}
	cout<<"YES"<<endl;
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 15984
final_rank: 8

code_snippet: #include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <cassert>
#include <fstream>
#include <utility>
#include <functional>
#include <time.h>
#include <stack>
#define popcount __builtin_popcount
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;

template<typename Monoid, typename OperatorMonoid=Monoid>
struct LazySegmentTree{
	using F=function<Monoid(Monoid, Monoid)>;
	using G=function<Monoid(Monoid, OperatorMonoid, int)>;
	using H=function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
	int sz;
	vector<Monoid> data;
	vector<OperatorMonoid> lazy;
	const F f;
	const G g;
	const H h;
	const Monoid e1;
	const OperatorMonoid e0;

	LazySegmentTree(int n, const F f, const G g, const H h, const Monoid &e1, const OperatorMonoid &e0): f(f), g(g), h(h), e1(e1), e0(e0){
		sz=1;
		while(sz<n) sz<<=1;
		data.resize(2*sz-1, e1);
		lazy.resize(2*sz-1, e0);
	}

	void build(vector<Monoid> v){
		for(int i=0; i<v.size(); i++) data[i+sz-1]=v[i];
		for(int i=sz-2; i>=0; i--) data[i]=f(data[2*i+1], data[2*i+2]);
	}

	void eval(int k, int l, int r){
		if(lazy[k]!=e0){
			data[k]=g(data[k], lazy[k], r-l);
			if(k<sz-1){
				lazy[2*k+1]=h(lazy[2*k+1], lazy[k]);
				lazy[2*k+2]=h(lazy[2*k+2], lazy[k]);
			}
		}
		lazy[k]=e0;
	}

	void update(int a, int b, const OperatorMonoid &x, int k, int l, int r){
		eval(k, l, r);
		if(r<=a || b<=l) return;
		if(a<=l && r<=b){
			lazy[k]=h(lazy[k], x);
			eval(k, l, r);
		}else{
			update(a, b, x, 2*k+1, l, (l+r)/2);
			update(a, b, x, 2*k+2, (l+r)/2, r);
			data[k]=f(data[2*k+1], data[2*k+2]);
		}
	}
	void update(int a, int b, const OperatorMonoid &x){
		return update(a, b, x, 0, 0, sz);
	}

	Monoid find(int a, int b, int k, int l, int r){
		eval(k, l, r);
		if(b<=l || r<=a) return e1;
		if(a<=l && r<=b) return data[k];
		else return f(find(a, b, 2*k+1, l, (l+r)/2), find(a, b, 2*k+2, (l+r)/2, r));
	}
	Monoid find(int a, int b){
		return find(a, b, 0, 0, sz);
	}
	Monoid operator[](const int &k){
		return find(k, k+1);
	}
};
template<typename Monoid>
struct SegmentTree{
	using F=function<Monoid(Monoid, Monoid)>;
	int sz;
	vector<Monoid> seg;
	const F f;
	const Monoid e;

	SegmentTree(int n, const F f, const Monoid &e): f(f), e(e){
		sz=1;
		while(sz<n) sz<<=1;
		seg.resize(2*sz, e);
	}

	SegmentTree(int n, const F f, const Monoid &e, vector<Monoid> v): f(f), e(e){
		sz=1;
		while(sz<n) sz<<=1;
		seg.resize(2*sz, e);
		for(int i=0; i<n; i++) seg[i+sz]=v[i];
		for(int i=sz-1; i>=1; i--){
			seg[i]=f(seg[2*i], seg[2*i+1]);
		}
	}

	void update(int k, const Monoid &x){
		k+=sz;
		seg[k]=x;
		while(k>1){
			k>>=1;
			seg[k]=f(seg[2*k], seg[2*k+1]);
		}
	}

	Monoid query(int a, int b){
		a+=sz, b+=sz;
		Monoid ret=e;
		for(;a<b; a>>=1, b>>=1){
			if(b&1) ret=f(ret, seg[--b]);
			if(a&1) ret=f(ret, seg[a++]);
		}
		return ret;
	}

	Monoid operator[](const int &k) const{
		return seg[k+sz];
	}
};
int q;
int t[50050], a[50050], b[50050], y[50050];
int s[50050];
vector<int> upd;
vector<int> va[100010], vb[100010];
int main()
{
	scanf("%d", &q);
	vector<int> v;
	for(int i=0; i<q; i++){
		scanf("%d %d %d %d", &t[i], &a[i], &b[i], &y[i]);
		a[i]--;
		v.push_back(a[i]);
		v.push_back(b[i]);
	}
	sort(v.begin(), v.end());
	v.erase(unique(v.begin(), v.end()), v.end());
	int m=v.size();
	auto f=[](int a, int b){ return min(a, b);};
	auto g=[](int a, int x, int len){ return x;};
	auto h=[](int x, int y){ return y;};
	const int INF=1e9+7;
	LazySegmentTree<int> seg1(m, f, g, h, INF, INF);
	for(int i=q-1; i>=0; i--){
		a[i]=lower_bound(v.begin(), v.end(), a[i])-v.begin();
		b[i]=lower_bound(v.begin(), v.end(), b[i])-v.begin();
		if(t[i]==1) seg1.update(a[i], b[i], i);
	}
	for(int i=0; i<m; i++) s[i]=seg1[i];
	auto f2=[](int a, int b){ return max(a, b);};
	SegmentTree<int> seg2(q, f2, -1);
	for(int i=0; i<q; i++){
		if(t[i]==0){
			va[a[i]].push_back(i);
			vb[b[i]].push_back(i);
		}
	}
	upd.resize(m);
	for(int i=0; i<m; i++){
		for(auto x:va[i]){
			seg2.update(x, y[x]);
		}
		for(auto x:vb[i]){
			seg2.update(x, -1);
		}
		upd[i]=seg2.query(0, min(q, s[i]));
		if(upd[i]==-1) upd[i]=INF;
	}
	LazySegmentTree<int> seg(m, f, g, h, INF, INF);
	seg.build(upd);
	for(int i=0; i<q; i++){
		if(t[i]==1) seg.update(a[i], b[i], y[i]);
		else if(seg.find(a[i], b[i])!=y[i]){
			cout<<"NO"<<endl;
			return 0;
		}
	}
	cout<<"YES"<<endl;
    return 0;
}
accuracy: 0.25925925925925924
time_ms: 50
memory_kb: 15984
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;


template<typename V>
V compress(V v){
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  return v;
}
template<typename T>
map<T, int> dict(const vector<T> &v){
  map<T, int> res;
  for(int i=0;i<(int)v.size();i++)
    res[v[i]]=i;
  return res;
}
map<char, int> dict(const string &v){
  return dict(vector<char>(v.begin(),v.end()));
}


template <typename E>
struct SegmentTree{
  using H = function<E(E,E)>;
  int n,height;
  H h;
  E ei;
  vector<E> laz;
  SegmentTree(H h,E ei):h(h),ei(ei){}
  void init(int n_){
    n=1;height=0;
    while(n<n_) n<<=1,height++;
    laz.assign(2*n,ei);
  }
  inline void eval(int k){
    if(laz[k]==ei) return;
    laz[(k<<1)|0]=h(laz[(k<<1)|0],laz[k]);
    laz[(k<<1)|1]=h(laz[(k<<1)|1],laz[k]);
    laz[k]=ei;
  }
  inline void thrust(int k){
    for(int i=height;i;i--) eval(k>>i);
  }
  void update(int a,int b,E x){
    thrust(a+=n);
    thrust(b+=n-1);
    for(int l=a,r=b+1;l<r;l>>=1,r>>=1){
      if(l&1) laz[l]=h(laz[l],x),l++;
      if(r&1) --r,laz[r]=h(laz[r],x);
    }
  }
  E get_val(int a){
    thrust(a+=n);
    return laz[a];
  }
  void set_val(int a,E x){
    thrust(a+=n);
    laz[a]=x;
  }
};


template <typename T,typename E>
struct SegmentTree2{
  using F = function<T(T,T)>;
  using G = function<T(T,E)>;
  using H = function<E(E,E)>;
  int n,height;
  F f;
  G g;
  H h;
  T ti;
  E ei;
  vector<T> dat;
  vector<E> laz;
  SegmentTree2(F f,G g,H h,T ti,E ei):
    f(f),g(g),h(h),ti(ti),ei(ei){}

  void init(int n_){
    n=1;height=0;
    while(n<n_) n<<=1,height++;
    dat.assign(2*n,ti);
    laz.assign(2*n,ei);
  }
  void build(const vector<T> &v){
    int n_=v.size();
    init(n_);
    for(int i=0;i<n_;i++) dat[n+i]=v[i];
    for(int i=n-1;i;i--)
      dat[i]=f(dat[(i<<1)|0],dat[(i<<1)|1]);
  }
  inline T reflect(int k){
    return laz[k]==ei?dat[k]:g(dat[k],laz[k]);
  }
  inline void eval(int k){
    if(laz[k]==ei) return;
    laz[(k<<1)|0]=h(laz[(k<<1)|0],laz[k]);
    laz[(k<<1)|1]=h(laz[(k<<1)|1],laz[k]);
    dat[k]=reflect(k);
    laz[k]=ei;
  }
  inline void thrust(int k){
    for(int i=height;i;i--) eval(k>>i);
  }
  inline void recalc(int k){
    while(k>>=1)
      dat[k]=f(reflect((k<<1)|0),reflect((k<<1)|1));
  }
  void update(int a,int b,E x){
    thrust(a+=n);
    thrust(b+=n-1);
    for(int l=a,r=b+1;l<r;l>>=1,r>>=1){
      if(l&1) laz[l]=h(laz[l],x),l++;
      if(r&1) --r,laz[r]=h(laz[r],x);
    }
    recalc(a);
    recalc(b);
  }
  void set_val(int a,T x){
    thrust(a+=n);
    dat[a]=x;laz[a]=ei;
    recalc(a);
  }
  T query(int a,int b){
    thrust(a+=n);
    thrust(b+=n-1);
    T vl=ti,vr=ti;
    for(int l=a,r=b+1;l<r;l>>=1,r>>=1) {
      if(l&1) vl=f(vl,reflect(l++));
      if(r&1) vr=f(reflect(--r),vr);
    }
    return f(vl,vr);
  }

  template<typename C>
  int find(int st,C &check,T &acc,int k,int l,int r){
    if(l+1==r){
      acc=f(acc,reflect(k));
      return check(acc)?k-n:-1;
    }
    eval(k);
    int m=(l+r)>>1;
    if(m<=st) return find(st,check,acc,(k<<1)|1,m,r);
    if(st<=l&&!check(f(acc,dat[k]))){
      acc=f(acc,dat[k]);
      return -1;
    }
    int vl=find(st,check,acc,(k<<1)|0,l,m);
    if(~vl) return vl;
    return find(st,check,acc,(k<<1)|1,m,r);
  }
  template<typename C>
  int find(int st,C &check){
    T acc=ti;
    return find(st,check,acc,1,0,n);
  }
};


template<typename T> void drop(const T &x){cout<<x<<endl;exit(0);}

//INSERT ABOVE HERE
signed main(){
  int q;
  cin>>q;
  vector<int> ts(q),as(q),bs(q),ys(q);
  for(int i=0;i<q;i++) cin>>ts[i]>>as[i]>>bs[i]>>ys[i];

  vector<int> vs;
  for(int i=0;i<q;i++){
    vs.emplace_back(as[i]-1);
    vs.emplace_back(as[i]);
    vs.emplace_back(as[i]+1);
    vs.emplace_back(bs[i]-1);
    vs.emplace_back(bs[i]);
    vs.emplace_back(bs[i]+1);
  }
  vs.emplace_back(0);
  vs.emplace_back(1e9+10);
  vs=compress(vs);
  auto dc=dict(vs);
  int m=dc.size();

  using P = pair<int, int>;
  auto h=[&](P a,P b){
           if(a.first) return a;
           return P(b.first,max(a.second,b.second));
         };
  P ei(0,0);
  SegmentTree<P> seg(h,ei);
  seg.init(m);

  for(int i=0;i<q;i++){
    int l=dc[as[i]];
    int r=dc[bs[i]+1];

    if(ts[i]==0) seg.update(l,r,P(0,ys[i]));
    if(ts[i]==1) seg.update(l,r,P(1,0));
  }

  vector<int> zs(m);
  for(int i=0;i<m;i++) zs[i]=seg.get_val(i).second;

  auto ff=[&](int a,int b){return min(a,b);};
  auto gg=[&](int a,int b){(void)a;return b;};
  SegmentTree2<int, int> seg2(ff,gg,gg,INT_MAX,-1);
  seg2.build(zs);

  for(int i=0;i<q;i++){
    int l=dc[as[i]];
    int r=dc[bs[i]+1];
    if(ts[i]==0){
      if(seg2.query(l,r)!=ys[i]) drop("NO");
    }
    if(ts[i]==1){
      seg2.update(l,r,ys[i]);
    }
  }
  drop("YES");
  return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 36704
final_rank: 13

code_snippet: #include <stdio.h>
#include <unordered_map>
#include <set>
#include <map>
#include <algorithm>

using namespace std;

int t[100000];
int a[100000];
int b[100000];
int y[100000];

bool ok[100000];

#define B 100

typedef struct
{
	int d[B];
	int n[B];
	bool l[B];
	int ad;
	int an;
	bool al;
	int m;
}point;

point d[200000 / B];

bool hazi(int o,int b,int e,int n)
{
	if(d[o].al)
	{
		if(d[o].an == y[n])
		{
			ok[n] = true;
		}
		else if(d[o].an < y[n])
		{
			return false;
		}
	}
	else
	{
		for(int i = b; i < e; i++)
		{
			if(d[o].l[i])
			{
				if(d[o].n[i] == y[n])
				{
					ok[n] = true;
				}
				else if(d[o].n[i] < y[n])
				{
					return false;
				}
			}
			else
			{
				if(d[o].d[i] < y[n])
				{
					d[o].d[i] = y[n];
				}
			}
		}
	}
	return true;
}

void hazi2(int o,int a,int e,int yw)
{
	if(d[o].al)
	{
		for(int i = 0; i < B; i++)
		{
			if(!d[o].l[i])
			{
				d[o].d[i] = max(d[o].d[i],d[o].ad);
			}
			d[o].n[i] = d[o].an;
			d[o].l[i] = true;
		}
		d[o].al = false;
	}
	for(int i = a; i < e; i++)
	{
		d[o].n[i] = yw;
		d[o].l[i] = true;
	}
	int minw = 1111111111;
	for(int i = 0; i < B; i++)
	{
		if(d[o].l[i])
		{
			minw = min(d[o].n[i],minw);
		}
	}
	d[o].m = minw;
}

bool naka(int o,int n)
{
	if(d[o].m == y[n])
	{
		ok[n] = true;
	}
	else if(d[o].m < y[n])
	{
		return false;
	}
	if(!d[o].al)
	{
		d[o].ad = max(d[o].ad,y[n]);
	}
	return true;
}

void naka2(int o,int yw)
{
	d[o].al = true;
	d[o].an = yw;
	d[o].m = yw;
}

void lastw(int o)
{
	for(int i = 0; i < B; i++)
	{
		if(!d[o].l[i])
		{
			d[o].d[i] = max(d[o].ad,d[o].d[i]);
		}
	}
}

pair<int,int> p[200000];

bool er[100000];

int main()
{
	int q;
	scanf("%d",&q);
	set<int> se;
	for(int i = 0; i < q; i++)
	{
		scanf("%d%d%d%d",t + i,a + i,b + i,y + i);
		se.insert(a[i]);
		se.insert(b[i] + 1);
		ok[i] = false;
	}
	unordered_map<int,int> mp;
	auto it = se.begin();
	int num = 0;
	for( ; it != se.end(); num++)
	{
		mp.insert({*it,num});
		it++;
	}
	for(int i = 0; i < 200000 / B; i++)
	{
		for(int ii = 0; ii < B; ii++)
		{
			d[i].d[ii] = 0;
			d[i].l[ii] = false;
		}
		d[i].ad = 0;
		d[i].al = false;
		d[i].m = 1111111111;
	}
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			if(aw / B == bw / B)
			{
				if(!hazi(aw / B,aw % B,bw % B,i))
				{
					printf("NO\n");
					return 0;
				}
			}
			else
			{
				if(!hazi(aw / B,aw % B,B,i))
				{
					printf("NO\n");
					return 0;
				}
				for(int ii = aw / B + 1; ii < bw / B; ii++)
				{
					if(!naka(ii,i))
					{
						printf("NO\n");
						return 0;
					}
				}
				if(!hazi(bw / B,0,bw % B,i))
				{
					printf("NO\n");
					return 0;
				}
			}
		}
		else
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			if(aw / B == bw / B)
			{
				hazi2(aw / B,aw % B,bw % B,y[i]);
			}
			else
			{
				hazi2(aw / B,aw % B,B,y[i]);
				for(int ii = aw / B + 1; ii < bw / B; ii++)
				{
					naka2(ii,y[i]);
				}
				hazi2(bw / B,0,bw % B,y[i]);
			}
		}
	}
	for(int i = 0; i < 200000 / B; i++)
	{
		lastw(i);
	}
	int nw = 0;
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			p[nw] = make_pair(aw,i);
			nw++;
			p[nw] = make_pair(bw,-i - 1);
			nw++;
			er[i] = false;
		}
	}
	sort(p,p + nw);
	multimap<int,int> se2;
	int nowb = 0;
	for(int i = 0; i < num; i++)
	{
		while(nowb < nw && p[nowb].first <= i)
		{
			if(p[nowb].second < 0)
			{
				int b = -p[nowb].second - 1;
				if(!er[b])
				{
					auto itw = se2.find(y[b]);
					while((*itw).second != b)
					{
						itw++;
					}
					se2.erase(itw);
				}
			}
			else
			{
				int b = p[nowb].second;
				se2.insert({y[b],b});
			}
			nowb++;
		}
		auto itt = se2.find(d[i / B].d[i % B]);
		while(itt != se2.end() && (*itt).first == d[i / B].d[i % B])
		{
			ok[(*itt).second] = true;
			er[(*itt).second] = true;
			auto itw = itt;
			itt++;
			se2.erase(itw);
		}
	}
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			if(!ok[i])
			{
				printf("NO\n");
				return 0;
			}
		}
	}
	printf("YES\n");
}
accuracy: 1
time_ms: 330
memory_kb: 14256
final_rank: 15

code_snippet: #include <stdio.h>
#include <unordered_map>
#include <set>
#include <map>
#include <algorithm>

using namespace std;

int t[100000];
int a[100000];
int b[100000];
int y[100000];

bool ok[100000];

#define B 100

typedef struct
{
	int d[B];
	int n[B];
	bool l[B];
	int ad;
	int an;
	bool al;
	int m;
}point;

point d[200000 / B];

bool hazi(int o,int b,int e,int n)
{
	if(d[o].al)
	{
		if(d[o].an == y[n])
		{
			ok[n] = true;
		}
		else if(d[o].an < y[n])
		{
			return false;
		}
	}
	else
	{
		for(int i = b; i < e; i++)
		{
			if(d[o].l[i])
			{
				if(d[o].n[i] == y[n])
				{
					ok[n] = true;
				}
				else if(d[o].n[i] < y[n])
				{
					return false;
				}
			}
			else
			{
				if(d[o].d[i] < y[n])
				{
					d[o].d[i] = y[n];
				}
			}
		}
	}
	return true;
}

void hazi2(int o,int a,int e,int yw)
{
	if(d[o].al)
	{
		for(int i = 0; i < B; i++)
		{
			if(!d[o].l[i])
			{
				d[o].d[i] = max(d[o].d[i],d[o].ad);
			}
			d[o].n[i] = d[o].an;
			d[o].l[i] = true;
		}
		d[o].al = false;
	}
	for(int i = a; i < e; i++)
	{
		d[o].n[i] = yw;
		d[o].l[i] = true;
	}
	int minw = 1111111111;
	for(int i = 0; i < B; i++)
	{
		if(d[o].l[i])
		{
			minw = min(d[o].n[i],minw);
		}
	}
	d[o].m = minw;
}

bool naka(int o,int n)
{
	if(d[o].m == y[n])
	{
		ok[n] = true;
	}
	else if(d[o].m < y[n])
	{
		return false;
	}
	if(!d[o].al)
	{
		d[o].ad = max(d[o].ad,y[n]);
	}
	return true;
}

void naka2(int o,int yw)
{
	d[o].al = true;
	d[o].an = yw;
	d[o].m = yw;
}

void lastw(int o)
{
	if(d[o].al)
	{
		for(int i = 0; i < B; i++)
		{
			if(!d[o].l[i])
			{
				d[o].d[i] = max(d[o].ad,d[o].d[i]);
			}
		}
	}
}

pair<int,int> p[200000];

bool er[100000];

int main()
{
	int q;
	scanf("%d",&q);
	set<int> se;
	for(int i = 0; i < q; i++)
	{
		scanf("%d%d%d%d",t + i,a + i,b + i,y + i);
		se.insert(a[i]);
		se.insert(b[i] + 1);
		ok[i] = false;
	}
	unordered_map<int,int> mp;
	auto it = se.begin();
	int num = 0;
	for( ; it != se.end(); num++)
	{
		mp.insert({*it,num});
		it++;
	}
	for(int i = 0; i < 200000 / B; i++)
	{
		for(int ii = 0; ii < B; ii++)
		{
			d[i].d[ii] = 0;
			d[i].l[ii] = false;
		}
		d[i].ad = 0;
		d[i].al = false;
		d[i].m = 1111111111;
	}
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			if(aw / B == bw / B)
			{
				if(!hazi(aw / B,aw % B,bw % B,i))
				{
					printf("NO\n");
					return 0;
				}
			}
			else
			{
				if(!hazi(aw / B,aw % B,B,i))
				{
					printf("NO\n");
					return 0;
				}
				for(int ii = aw / B + 1; ii < bw / B; ii++)
				{
					if(!naka(ii,i))
					{
						printf("NO\n");
						return 0;
					}
				}
				if(!hazi(bw / B,0,bw % B,i))
				{
					printf("NO\n");
					return 0;
				}
			}
		}
		else
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			if(aw / B == bw / B)
			{
				hazi2(aw / B,aw % B,bw % B,y[i]);
			}
			else
			{
				hazi2(aw / B,aw % B,B,y[i]);
				for(int ii = aw / B + 1; ii < bw / B; ii++)
				{
					naka2(ii,y[i]);
				}
				hazi2(bw / B,0,bw % B,y[i]);
			}
		}
	}
	for(int i = 0; i < 200000 / B; i++)
	{
		lastw(i);
	}
	int nw = 0;
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			p[nw] = make_pair(aw,i);
			nw++;
			p[nw] = make_pair(bw,-i - 1);
			nw++;
			er[i] = false;
		}
	}
	sort(p,p + nw);
	multimap<int,int> se2;
	int nowb = 0;
	for(int i = 0; i < num; i++)
	{
		while(nowb < nw && p[nowb].first <= i)
		{
			if(p[nowb].second < 0)
			{
				int b = -p[nowb].second - 1;
				if(!er[b])
				{
					auto itw = se2.find(y[b]);
					while((*itw).second != b)
					{
						itw++;
					}
					se2.erase(itw);
				}
			}
			else
			{
				int b = p[nowb].second;
				se2.insert({y[b],b});
			}
			nowb++;
		}
		auto itt = se2.find(d[i / B].d[i % B]);
		while(itt != se2.end() && (*itt).first == d[i / B].d[i % B])
		{
			ok[(*itt).second] = true;
			er[(*itt).second] = true;
			auto itw = itt;
			itt++;
			se2.erase(itw);
		}
	}
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			if(!ok[i])
			{
				printf("NO\n");
				return 0;
			}
		}
	}
	printf("YES\n");
}
accuracy: 0.9259259259259259
time_ms: 130
memory_kb: 14256
final_rank: 16

code_snippet: #include <stdio.h>
#include <unordered_map>
#include <set>
#include <map>
#include <algorithm>

using namespace std;

int t[100000];
int a[100000];
int b[100000];
int y[100000];

bool ok[100000];

#define B 100

typedef struct
{
	int d[B];
	int n[B];
	bool l[B];
	int ad;
	int an;
	bool al;
	int m;
}point;

point d[200000 / B];

bool hazi(int o,int b,int e,int n)
{
	if(d[o].al)
	{
		if(d[o].an == y[n])
		{
			ok[n] = true;
		}
		else if(d[o].an < y[n])
		{
			return false;
		}
	}
	else
	{
		for(int i = b; i < e; i++)
		{
			if(d[o].l[i])
			{
				if(d[o].n[i] == y[n])
				{
					ok[n] = true;
				}
				else if(d[o].n[i] < y[n])
				{
					return false;
				}
			}
			else
			{
				if(d[o].d[i] < y[n])
				{
					d[o].d[i] = y[n];
				}
			}
		}
	}
	return true;
}

void hazi2(int o,int a,int b,int yw)
{
	if(d[o].al)
	{
		for(int i = 0; i < B; i++)
		{
			if(!d[o].l[i])
			{
				d[o].d[i] = max(d[o].d[i],d[o].ad);
			}
			d[o].n[i] = d[o].an;
			d[o].l[i] = true;
		}
		d[o].al = false;
	}
	for(int i = a; i < b; i++)
	{
		d[o].n[i] = yw;
		d[o].l[i] = true;
	}
	int minw = 1111111111;
	for(int i = 0; i < B; i++)
	{
		minw = min(d[o].n[i],minw);
	}
	d[o].m = minw;
}

bool naka(int o,int n)
{
	if(d[o].m == y[n])
	{
		ok[n] = true;
	}
	else if(d[o].m < y[n])
	{
		return false;
	}
	if(!d[o].al)
	{
		d[o].ad = max(d[o].ad,y[n]);
	}
	return true;
}

void naka2(int o,int yw)
{
	d[o].al = true;
	d[o].an = yw;
	d[o].m = yw;
}

void lastw(int o)
{
	if(d[o].al)
	{
		for(int i = 0; i < B; i++)
		{
			if(!d[o].l[i])
			{
				d[o].d[i] = max(d[o].ad,d[o].d[i]);
			}
		}
	}
}

pair<int,int> p[200000];

bool er[100000];

int main()
{
	int q;
	scanf("%d",&q);
	set<int> se;
	for(int i = 0; i < q; i++)
	{
		scanf("%d%d%d%d",t + i,a + i,b + i,y + i);
		se.insert(a[i]);
		se.insert(b[i] + 1);
	}
	unordered_map<int,int> mp;
	auto it = se.begin();
	int num = 0;
	for( ; it != se.end(); num++)
	{
		mp.insert({*it,num});
		ok[num] = false;
		it++;
	}
	for(int i = 0; i < 200000 / B; i++)
	{
		for(int ii = 0; ii < B; ii++)
		{
			d[i].d[ii] = 0;
			d[i].l[ii] = false;
		}
		d[i].ad = 0;
		d[i].al = false;
		d[i].m = 1111111111;
	}
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			if(aw / B == bw / B)
			{
				if(!hazi(aw / B,aw % B,bw % B,i))
				{
					printf("NO\n");
					return 0;
				}
			}
			else
			{
				if(!hazi(aw / B,aw % B,B,i))
				{
					printf("NO\n");
					return 0;
				}
				for(int ii = aw / B + 1; ii < bw / B; ii++)
				{
					if(!naka(ii,i))
					{
						printf("NO\n");
						return 0;
					}
				}
				if(!hazi(bw / B,0,bw % B,i))
				{
					printf("NO\n");
					return 0;
				}
			}
		}
		else
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			if(aw / B == bw / B)
			{
				hazi2(aw / B,aw % B,bw % B,y[i]);
			}
			else
			{
				hazi2(aw / B,aw % B,B,y[i]);
				for(int ii = aw / B + 1; ii < bw / B; ii++)
				{
					naka2(ii,y[i]);
				}
				hazi2(bw / B,0,bw % B,y[i]);
			}
		}
	}
	for(int i = 0; i < 200000 / B; i++)
	{
		lastw(i);
	}
	int nw = 0;
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			int aw = mp[a[i]];
			int bw = mp[b[i] + 1];
			p[nw] = make_pair(aw,i);
			nw++;
			p[nw] = make_pair(bw,-i - 1);
			nw++;
			er[i] = false;
		}
	}
	sort(p,p + nw);
	multimap<int,int> se2;
	int nowb = 0;
	for(int i = 0; i < num; i++)
	{
		while(nowb < nw && p[nowb].first <= i)
		{
			if(p[nowb].second < 0)
			{
				int b = -p[nowb].second - 1;
				if(!er[b])
				{
					auto itw = se2.find(y[b]);
					while((*itw).second != b)
					{
						itw++;
					}
					se2.erase(itw);
				}
			}
			else
			{
				int b = p[nowb].second;
				se2.insert({y[b],b});
			}
			nowb++;
		}
		auto itt = se2.find(d[i / B].d[i % B]);
		while(itt != se2.end() && (*itt).first == d[i / B].d[i % B])
		{
			ok[(*itt).second] = true;
			er[(*itt).second] = true;
			auto itw = itt;
			itt++;
			se2.erase(itw);
		}
	}
	for(int i = 0; i < q; i++)
	{
		if(t[i] == 0)
		{
			if(!ok[i])
			{
				printf("NO\n");
				return 0;
			}
		}
	}
	printf("YES\n");
}
accuracy: 0.25925925925925924
time_ms: 40
memory_kb: 13992
final_rank: 17

code_snippet: #include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

const int INF = int(1.05e9);

class SegMax {
	int N;
	vector<int> maxi;
	inline void doit(int k, int x) {maxi[k] = max(maxi[k], x);}
public:
	SegMax(int n) : N(n == 1 ? 1 : 1<<(32 - __builtin_clz(n - 1))), maxi(2*N, 0) {}
	int query(int k) {
		int ans = 0;
		for (k+=N;k>0;k>>=1) ans = max(ans, maxi[k]);
		return ans;
	}

	void fill(int L, int R, int x) {
		for(L+=N,R+=N;L<R;L>>=1,R>>=1){
			if(R&1) doit(--R,x);
			if(L&1) doit(L++,x);
		}
	}
};

class SegRMQ {
	int N;
	vector<pair<int, bool> > datas;//(mini, uniform)
	inline void update(int k) {
		datas[k].first = min(datas[2*k].first, datas[2*k+1].first);
	}
	inline void prop(int k) {
		if (datas[k].second) {
			datas[2*k] = datas[2*k+1] = datas[k];
			datas[k].second = false;
		}
	}
public:
	SegRMQ(const vector<int>& ns) {
		N = ns.size() == 1 ? 1 : 1<<(32 - __builtin_clz(int(ns.size())-1));
		datas.assign(2*N, make_pair(INF, false));
		for (int i = 0; i < int(ns.size()); ++i) {
			datas[i+N].first = ns[i];
		}
		for (int i = N - 1 ; i > 0; --i) update(i);
	}

	int getMin(int L, int R) {
		static int inds[128], len;
		len = 0;
		for(int a=L?(N+L)/(L&-L)/2:0,b=R?((N+R)/(R&-R)-1)/2:0;;b>>=1){
			if(a==b){
				for(;a;a>>=1) inds[len++]=a;
				break;
			}
			if(a>b) swap(a,b);
			inds[len++] = b;
		}
		for(int i=len-1; i>=0; --i) prop(inds[i]);
		int ans = INF;
		for(L+=N,R+=N;L<R;L>>=1,R>>=1){
			if(R&1) ans = min(ans, datas[--R].first);
			if(L&1) ans = min(ans, datas[L++].first);
		}
		return ans;
	}

	void fill(int L, int R, int x) {
		static int inds[128], len;
		len = 0;
		for(int a=L?(N+L)/(L&-L)/2:0,b=R?((N+R)/(R&-R)-1)/2:0;;b>>=1){
			if(a==b){
				for(;a;a>>=1) inds[len++]=a;
				break;
			}
			if(a>b) swap(a,b);
			inds[len++] = b;
		}
		for(int i=len-1; i>=0; --i) prop(inds[i]);
		for(L+=N,R+=N;L<R;L>>=1,R>>=1){
			if(R&1) datas[--R] = make_pair(x,true);
			if(L&1) datas[L++] = make_pair(x,true);
		}
		for(int i=0; i<len; ++i) update(inds[i]);
	}
};

const int MAX_N = int(5e4);
int as[MAX_N], bs[MAX_N], ys[MAX_N], ns[2*MAX_N], ts[MAX_N];

int main() {
	int n; scanf("%d", &n);
	int L = 0;
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d", ts+i, as+i, bs+i, ys+i);
		++bs[i];
		ns[L++] = as[i];
		ns[L++] = bs[i];
	}
	sort(ns, ns + L);
	L = unique(ns, ns+L) - ns;
	for (int i = 0; i < n; ++i) {
		as[i] = lower_bound(ns, ns+L, as[i]) - ns;
		bs[i] = lower_bound(ns, ns+L, bs[i]) - ns;
	}

	SegMax seg(L);
	set<int> ids;
	vector<int> xs(L);
	for (int i = 0; i < L; ++i) {
		ids.insert(i);
	}
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0) {
			seg.fill(as[i], bs[i], ys[i]);
		}
		else {
			for (set<int>::iterator itr = ids.lower_bound(as[i]); itr != ids.end() && *itr < bs[i]; ids.erase(itr++)) {
				xs[*itr] = seg.query(*itr);
			}
		}
	}
	for (set<int>::iterator itr = ids.begin(); itr != ids.end(); ++itr) {
		xs[*itr] = seg.query(*itr);
	}
	SegRMQ rmq(xs);
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0 && rmq.getMin(as[i], bs[i]) != ys[i]) {
			puts("NO");
			return 0;
		}
		else if (ts[i] == 1) {
			rmq.fill(as[i], bs[i], ys[i]);
		}
	}
	puts("YES");

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 8124
final_rank: 1

code_snippet: #include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

const int INF = int(1.05e9);

inline unsigned int getHighestOneBit(unsigned int x) {
	/*
	x |= (x >> 1);
	x |= (x >> 2);
	x |= (x >> 4);
	x |= (x >> 8);
	x |= (x >> 16);
	return x & ~(x >> 1);
	*/
	return 1<<(31 - __builtin_clz(x));
}

class SegMax {
	int N;
	vector<int> maxi;
	inline void doit(int k, int x) {maxi[k] = max(maxi[k], x);}
public:
	SegMax(int n) : N(n == 1 ? 1 : 1<<(32 - __builtin_clz(n - 1))), maxi(2*N, 0) {}
	int query(int k) {
		int ans = 0;
		for (k+=N;k>0;k>>=1) ans = max(ans, maxi[k]);
		return ans;
	}

	void fill(int s, int t, int x) {
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) doit(idx, x);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) doit(idx, x);
	}
};

class SegRMQ {
	int N;
	vector<pair<int, bool> > datas;//(mini, uniform)
	inline void update(int k) {
		datas[k].first = min(datas[2*k].first, datas[2*k+1].first);
	}
	inline void prop(int k) {
		if (datas[k].second) {
			datas[2*k] = datas[2*k+1] = datas[k];
			datas[k].second = false;
		}
	}
	inline int getWidth(int i) {
		return N / getHighestOneBit(i);
	}
public:
	SegRMQ(const vector<int>& ns) {
		N = ns.size() == 1 ? 1 : 1<<(32 - __builtin_clz(int(ns.size())-1));
		datas.assign(2*N, make_pair(INF, false));
		for (int i = 0; i < int(ns.size()); ++i) {
			datas[i+N].first = ns[i];
		}
		for (int i = N - 1 ; i > 0; --i) update(i);
	}

	int getMin(int L, int R) {
		static int inds[128], len;
		len = 0;
		for(int a=L?(N+L)/(L&-L)/2:0,b=R?((N+R)/(R&-R)-1)/2:0;;b>>=1){
			if(a==b){
				for(;a;a>>=1) inds[len++]=a;
				break;
			}
			if(a>b) swap(a,b);
			inds[len++] = b;
		}
		for(int i=len-1; i>=0; --i) prop(inds[i]);
		int ans = INF;
		for (int idx;0<L && L+(L&-L)<=R && (idx=(N+L)/(L&-L)); L+=L&-L) ans = min(ans, datas[idx].first);
		for (int idx;L<R && (idx=(N+R)/(R&-R)-1); R-=R&-R) ans = min(ans, datas[idx].first);
		return ans;
	}

	void fill(int L, int R, int x) {
		static int inds[128], len;
		len = 0;
		for(int a=L?(N+L)/(L&-L)/2:0,b=R?((N+R)/(R&-R)-1)/2:0;;b>>=1){
			if(a==b){
				for(;a;a>>=1) inds[len++]=a;
				break;
			}
			if(a>b) swap(a,b);
			inds[len++] = b;
		}
		for(int i=len-1; i>=0; --i) prop(inds[i]);
		for (int idx;0<L && L+(L&-L)<=R && (idx=(N+L)/(L&-L)); L+=L&-L) datas[idx] = make_pair(x,true);
		for (int idx;L<R && (idx=(N+R)/(R&-R)-1); R-=R&-R) datas[idx] = make_pair(x,true);
		for(int i=0; i<len; ++i) update(inds[i]);
	}
};

const int MAX_N = int(5e4);
int as[MAX_N], bs[MAX_N], ys[MAX_N], ns[2*MAX_N], ts[MAX_N];

int main() {
	int n; scanf("%d", &n);
	int L = 0;
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d", ts+i, as+i, bs+i, ys+i);
		++bs[i];
		ns[L++] = as[i];
		ns[L++] = bs[i];
	}
	sort(ns, ns + L);
	L = unique(ns, ns+L) - ns;
	for (int i = 0; i < n; ++i) {
		as[i] = lower_bound(ns, ns+L, as[i]) - ns;
		bs[i] = lower_bound(ns, ns+L, bs[i]) - ns;
	}

	SegMax seg(L);
	set<int> ids;
	vector<int> xs(L);
	for (int i = 0; i < L; ++i) {
		ids.insert(i);
	}
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0) {
			seg.fill(as[i], bs[i], ys[i]);
		}
		else {
			for (set<int>::iterator itr = ids.lower_bound(as[i]); itr != ids.end() && *itr < bs[i]; ids.erase(itr++)) {
				xs[*itr] = seg.query(*itr);
			}
		}
	}
	for (set<int>::iterator itr = ids.begin(); itr != ids.end(); ++itr) {
		xs[*itr] = seg.query(*itr);
	}
	SegRMQ rmq(xs);
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0 && rmq.getMin(as[i], bs[i]) != ys[i]) {
			puts("NO");
			return 0;
		}
		else if (ts[i] == 1) {
			rmq.fill(as[i], bs[i], ys[i]);
		}
	}
	puts("YES");

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 8124
final_rank: 1

code_snippet: #include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

const int INF = int(1.05e9);

inline unsigned int getHighestOneBit(unsigned int x) {
	/*
	x |= (x >> 1);
	x |= (x >> 2);
	x |= (x >> 4);
	x |= (x >> 8);
	x |= (x >> 16);
	return x & ~(x >> 1);
	*/
	return 1<<(31 - __builtin_clz(x));
}

class SegMax {
	int N;
	vector<int> maxi;
	inline void doit(int k, int x) {maxi[k] = max(maxi[k], x);}
public:
	SegMax(int n) : N(n == 1 ? 1 : 1<<(32 - __builtin_clz(n - 1))), maxi(2*N, 0) {}
	int query(int k) {
		int ans = 0;
		for (k+=N;k>0;k>>=1) ans = max(ans, maxi[k]);
		return ans;
	}

	void fill(int s, int t, int x) {
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) doit(idx, x);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) doit(idx, x);
	}
};

class SegRMQ {
	int N;
	vector<pair<int, bool> > datas;//(mini, uniform)
	inline void update(int k) {
		datas[k].first = min(datas[2*k].first, datas[2*k+1].first);
	}
	inline void prop(int k) {
		if (datas[k].second) {
			datas[2*k] = datas[2*k+1] = datas[k];
			datas[k].second = false;
		}
	}
	inline int getWidth(int i) {
		return N / getHighestOneBit(i);
	}
public:
	SegRMQ(const vector<int>& ns) {
		N = ns.size() == 1 ? 1 : 1<<(32 - __builtin_clz(int(ns.size())-1));
		datas.assign(2*N, make_pair(INF, false));
		for (int i = 0; i < int(ns.size()); ++i) {
			datas[i+N].first = ns[i];
		}
		for (int i = N - 1 ; i > 0; --i) update(i);
	}

	int getMin(int L, int R) {
		static int ls[128], rs[128], inds[128], l, r, len;
		l = r = -1;
		if(L)for(int k=(N+L)/(L&-L);k>>=1;) ls[++l] = k;
		if(R)for(int k=(N+R)/(R&-R)-1;k>>=1;) rs[++r] = k;
		for(len=0;(~l)||(~r);){
			if(!(~l)) inds[len++]=rs[r--];
			else if(!(~r)) inds[len++]=ls[l--];
			else{
				if(ls[l] == rs[r]){
					inds[len++] = ls[l--];
					r--;
				}
				else if(ls[l] < rs[r]){
					inds[len++] = ls[l--];
				}
				else {
					inds[len++] = rs[r--];
				}
			}
		}
		for(int i=0; i<len; ++i) prop(inds[i]);
		int ans = INF;
		for (int idx;0<L && L+(L&-L)<=R && (idx=(N+L)/(L&-L)); L+=L&-L) ans = min(ans, datas[idx].first);
		for (int idx;L<R && (idx=(N+R)/(R&-R)-1); R-=R&-R) ans = min(ans, datas[idx].first);
		return ans;
	}

	void fill(int L, int R, int x) {
		static int ls[128], rs[128], inds[128], l, r, len;
		l = r = -1;
		if(L)for(int k=(N+L)/(L&-L);k>>=1;) ls[++l] = k;
		if(R)for(int k=(N+R)/(R&-R)-1;k>>=1;) rs[++r] = k;
		for(len=0;(~l)||(~r);){
			if(!(~l)) inds[len++]=rs[r--];
			else if(!(~r)) inds[len++]=ls[l--];
			else{
				if(ls[l] == rs[r]){
					inds[len++] = ls[l--];
					r--;
				}
				else if(ls[l] < rs[r]){
					inds[len++] = ls[l--];
				}
				else {
					inds[len++] = rs[r--];
				}
			}
		}
		for(int i=0; i<len; ++i) prop(inds[i]);
		for (int idx;0<L && L+(L&-L)<=R && (idx=(N+L)/(L&-L)); L+=L&-L) datas[idx] = make_pair(x,true);
		for (int idx;L<R && (idx=(N+R)/(R&-R)-1); R-=R&-R) datas[idx] = make_pair(x,true);
		for(int i=len; --i;) update(inds[i]);
	}
};

const int MAX_N = int(5e4);
int as[MAX_N], bs[MAX_N], ys[MAX_N], ns[2*MAX_N], ts[MAX_N];

int main() {
	int n; scanf("%d", &n);
	int L = 0;
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d", ts+i, as+i, bs+i, ys+i);
		++bs[i];
		ns[L++] = as[i];
		ns[L++] = bs[i];
	}
	sort(ns, ns + L);
	L = unique(ns, ns+L) - ns;
	for (int i = 0; i < n; ++i) {
		as[i] = lower_bound(ns, ns+L, as[i]) - ns;
		bs[i] = lower_bound(ns, ns+L, bs[i]) - ns;
	}

	SegMax seg(L);
	set<int> ids;
	vector<int> xs(L);
	for (int i = 0; i < L; ++i) {
		ids.insert(i);
	}
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0) {
			seg.fill(as[i], bs[i], ys[i]);
		}
		else {
			for (set<int>::iterator itr = ids.lower_bound(as[i]); itr != ids.end() && *itr < bs[i]; ids.erase(itr++)) {
				xs[*itr] = seg.query(*itr);
			}
		}
	}
	for (set<int>::iterator itr = ids.begin(); itr != ids.end(); ++itr) {
		xs[*itr] = seg.query(*itr);
	}
	SegRMQ rmq(xs);
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0 && rmq.getMin(as[i], bs[i]) != ys[i]) {
			puts("NO");
			return 0;
		}
		else if (ts[i] == 1) {
			rmq.fill(as[i], bs[i], ys[i]);
		}
	}
	puts("YES");

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 8124
final_rank: 1

code_snippet: #include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

const int INF = int(1.05e9);

inline unsigned int getHighestOneBit(unsigned int x) {
	/*
	x |= (x >> 1);
	x |= (x >> 2);
	x |= (x >> 4);
	x |= (x >> 8);
	x |= (x >> 16);
	return x & ~(x >> 1);
	*/
	return 1<<(31 - __builtin_clz(x));
}

class SegMax {
	int N;
	vector<int> maxi;
	inline void doit(int k, int x) {maxi[k] = max(maxi[k], x);}
public:
	SegMax(int n) : N(n == 1 ? 1 : 1<<(32 - __builtin_clz(n - 1))), maxi(2*N, 0) {}
	int query(int k) {
		int ans = 0;
		for (k+=N;k>0;k>>=1) ans = max(ans, maxi[k]);
		return ans;
	}

	void fill(int s, int t, int x) {
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) doit(idx, x);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) doit(idx, x);
	}
};

class SegRMQ {
	int N;
	vector<pair<int, bool> > datas;//(mini, uniform)
	inline void update(int k) {
		datas[k].first = min(datas[2*k].first, datas[2*k+1].first);
	}
	inline void prop(int k) {
		if (datas[k].second) {
			datas[2*k] = datas[2*k+1] = datas[k];
			datas[k].second = false;
		}
	}
	inline int getWidth(int i) {
		return N / getHighestOneBit(i);
	}
public:
	SegRMQ(const vector<int>& ns) {
		N = ns.size() == 1 ? 1 : 1<<(32 - __builtin_clz(int(ns.size())-1));
		datas.assign(2*N, make_pair(INF, false));
		for (int i = 0; i < int(ns.size()); ++i) {
			datas[i+N].first = ns[i];
		}
		for (int i = N - 1 ; i > 0; --i) update(i);
	}

	int getMin(int L, int R) {
		static int inds[128], len;
		len = 0;
		if(L)for(int k=(N+L)/(L&-L);k>>=1;) inds[len++] = k;
		if(R)for(int k=(N+R)/(R&-R)-1;k>>=1;) inds[len++] = k;
		sort(inds, inds+len);
		len = unique(inds, inds+len) - inds;
		for(int i=0; i<len; ++i) prop(inds[i]);
		int ans = INF;
		for (int idx;0<L && L+(L&-L)<=R && (idx=(N+L)/(L&-L)); L+=L&-L) ans = min(ans, datas[idx].first);
		for (int idx;L<R && (idx=(N+R)/(R&-R)-1); R-=R&-R) ans = min(ans, datas[idx].first);
		return ans;
	}

	void fill(int L, int R, int x) {
		static int inds[128], len;
		len = 0;
		if(L)for(int k=(N+L)/(L&-L);k>>=1;) inds[len++] = k;
		if(R)for(int k=(N+R)/(R&-R)-1;k>>=1;) inds[len++] = k;
		sort(inds, inds+len);
		len = unique(inds, inds+len) - inds;
		for(int i=0; i<len; ++i) prop(inds[i]);
		for (int idx;0<L && L+(L&-L)<=R && (idx=(N+L)/(L&-L)); L+=L&-L) datas[idx] = make_pair(x,true);
		for (int idx;L<R && (idx=(N+R)/(R&-R)-1); R-=R&-R) datas[idx] = make_pair(x,true);
		for(int i=len; --i;) update(inds[i]);
	}
};

const int MAX_N = int(5e4);
int as[MAX_N], bs[MAX_N], ys[MAX_N], ns[2*MAX_N], ts[MAX_N];

int main() {
	int n; scanf("%d", &n);
	int L = 0;
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d", ts+i, as+i, bs+i, ys+i);
		++bs[i];
		ns[L++] = as[i];
		ns[L++] = bs[i];
	}
	sort(ns, ns + L);
	L = unique(ns, ns+L) - ns;
	for (int i = 0; i < n; ++i) {
		as[i] = lower_bound(ns, ns+L, as[i]) - ns;
		bs[i] = lower_bound(ns, ns+L, bs[i]) - ns;
	}

	SegMax seg(L);
	set<int> ids;
	vector<int> xs(L);
	for (int i = 0; i < L; ++i) {
		ids.insert(i);
	}
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0) {
			seg.fill(as[i], bs[i], ys[i]);
		}
		else {
			for (set<int>::iterator itr = ids.lower_bound(as[i]); itr != ids.end() && *itr < bs[i]; ids.erase(itr++)) {
				xs[*itr] = seg.query(*itr);
			}
		}
	}
	for (set<int>::iterator itr = ids.begin(); itr != ids.end(); ++itr) {
		xs[*itr] = seg.query(*itr);
	}
	SegRMQ rmq(xs);
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0 && rmq.getMin(as[i], bs[i]) != ys[i]) {
			puts("NO");
			return 0;
		}
		else if (ts[i] == 1) {
			rmq.fill(as[i], bs[i], ys[i]);
		}
	}
	puts("YES");

	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 8124
final_rank: 6

code_snippet: #include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

const int INF = int(1.05e9);

inline unsigned int getHighestOneBit(unsigned int x) {
	/*
	x |= (x >> 1);
	x |= (x >> 2);
	x |= (x >> 4);
	x |= (x >> 8);
	x |= (x >> 16);
	return x & ~(x >> 1);
	*/
	return 1<<(31 - __builtin_clz(x));
}

class SegMax {
	int N;
	vector<int> maxi;
	inline void doit(int k, int x) {maxi[k] = max(maxi[k], x);}
public:
	SegMax(int n) : N(n == 1 ? 1 : 1<<(32 - __builtin_clz(n - 1))), maxi(2*N, 0) {}
	int query(int k) {
		int ans = 0;
		for (k+=N;k>0;k>>=1) ans = max(ans, maxi[k]);
		return ans;
	}

	void fill(int s, int t, int x) {
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) doit(idx, x);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) doit(idx, x);
	}
};

class SegRMQ {
	int N;
	vector<pair<int, bool> > datas;//(mini, uniform)
	inline void update(int k) {
		datas[k].first = min(datas[2*k].first, datas[2*k+1].first);
	}
	inline void prop(int k) {
		if (datas[k].second) {
			datas[2*k] = datas[2*k+1] = datas[k];
			datas[k].second = false;
		}
	}
	inline int getWidth(int i) {
		return N / getHighestOneBit(i);
	}
public:
	SegRMQ(const vector<int>& ns) {
		N = ns.size() == 1 ? 1 : 1<<(32 - __builtin_clz(int(ns.size())-1));
		datas.assign(2*N, make_pair(INF, false));
		for (int i = 0; i < int(ns.size()); ++i) {
			datas[i+N].first = ns[i];
		}
		for (int i = N - 1 ; i > 0; --i) update(i);
	}

	int getMin(int L, int R) {
		int hw = N/2, k = 1, l = 0, ans = INF;
		for(;k<N && R-L!=2*hw;k=2*k+(R>l+hw),l+=(R>l+hw?hw:0),hw>>=1){
			prop(k);
			if(R > l + hw && l + hw > L) break;
		}
		if(R-L==2*hw || k>=N){
			return datas[k].first;
		}

		for(int lk=k*2,lw=getWidth(lk),ll=lk*lw-N;;){
			if(ll==L){
				ans = min(ans, datas[lk].first);
				break;
			}
			prop(lk);
			lk = 2*lk + 1;
			lw >>= 1;
			if(L<ll+lw){
				ans = min(ans, datas[lk].first);
				lk ^= 1;
			}
			else{
				ll += lw;
			}
		}

		for(int rk=2*k+1,rw=getWidth(rk),rl=rk*rw-N;;){
			if(rl+rw==R){
				ans = min(ans, datas[rk].first);
				break;
			}
			prop(rk);
			rk = 2*rk;
			rw >>= 1;
			if(rl+rw<R){
				ans = min(ans,datas[rk].first);
				rk ^= 1;
				rl += rw;
			}
		}

		return ans;
	}

	void fill(int L, int R, int x) {
		int hw = N/2, k = 1, l = 0;
		for(;k<N && R-L!=2*hw;k=2*k+(R>l+hw),l+=(R>l+hw?hw:0),hw>>=1){
			prop(k);
			if(R > l + hw && l + hw > L) break;
		}
		if(R-L==2*hw || k>=N){
			datas[k] = make_pair(x,true);
			for(;k>>=1;) update(k);
			return ;
		}

		for(int lk=k*2,lw=getWidth(lk),ll=lk*lw-N;;){
			if(ll==L){
				datas[lk] = make_pair(x,true);
				for (;(lk>>=1)>k;) update(lk);
				break;
			}
			prop(lk);
			lk = 2*lk + 1;
			lw >>= 1;
			if(L<ll+lw){
				datas[lk] = make_pair(x,true);
				lk ^= 1;
			}
			else{
				ll += lw;
			}
		}

		for(int rk=2*k+1,rw=getWidth(rk),rl=rk*rw-N;;){
			if(rl+rw==R){
				datas[rk] = make_pair(x,true);
				for (;rk>>=1;) update(rk);
				break;
			}
			prop(rk);
			rk = 2*rk;
			rw >>= 1;
			if(rl+rw<R){
				datas[rk] = make_pair(x,true);
				rk ^= 1;
				rl += rw;
			}
		}
	}
};

const int MAX_N = int(5e4);
int as[MAX_N], bs[MAX_N], ys[MAX_N], ns[2*MAX_N], ts[MAX_N];

int main() {
	int n; scanf("%d", &n);
	int L = 0;
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d", ts+i, as+i, bs+i, ys+i);
		++bs[i];
		ns[L++] = as[i];
		ns[L++] = bs[i];
	}
	sort(ns, ns + L);
	L = unique(ns, ns+L) - ns;
	for (int i = 0; i < n; ++i) {
		as[i] = lower_bound(ns, ns+L, as[i]) - ns;
		bs[i] = lower_bound(ns, ns+L, bs[i]) - ns;
	}

	SegMax seg(L);
	set<int> ids;
	vector<int> xs(L);
	for (int i = 0; i < L; ++i) {
		ids.insert(i);
	}
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0) {
			seg.fill(as[i], bs[i], ys[i]);
		}
		else {
			for (set<int>::iterator itr = ids.lower_bound(as[i]); itr != ids.end() && *itr < bs[i]; ids.erase(itr++)) {
				xs[*itr] = seg.query(*itr);
			}
		}
	}
	for (set<int>::iterator itr = ids.begin(); itr != ids.end(); ++itr) {
		xs[*itr] = seg.query(*itr);
	}
	SegRMQ rmq(xs);
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0 && rmq.getMin(as[i], bs[i]) != ys[i]) {
			puts("NO");
			return 0;
		}
		else if (ts[i] == 1) {
			rmq.fill(as[i], bs[i], ys[i]);
		}
	}
	puts("YES");

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 8124
final_rank: 1

code_snippet: #include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

const int INF = int(1.05e9); 

class SegMax {
	int N;
	vector<int> maxi;
	inline void doit(int k, int x) {maxi[k] = max(maxi[k], x);}
public:
	SegMax(int n) : N(n == 1 ? 1 : 1<<(32 - __builtin_clz(n - 1))), maxi(2*N, 0) {}
	int query(int k) {
		int ans = 0;
		for (k+=N;k>0;k>>=1) ans = max(ans, maxi[k]);
		return ans;
	}

	void fill(int s, int t, int x) {
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) doit(idx, x);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) doit(idx, x);
	}
};

class SegRMQ {
	int N;
	vector<pair<int, bool> > datas;//(mini, uniform)
	inline void update(int k) {
		datas[k].first = min(datas[2*k].first, datas[2*k+1].first);
	}
	inline void prop(int k) {
		if (datas[k].second) {
			datas[2*k] = datas[2*k+1] = datas[k];
			datas[k].second = false;
		}
	}
public:
	SegRMQ(const vector<int>& ns) {
		N = ns.size() == 1 ? 1 : 1<<(32 - __builtin_clz(int(ns.size())-1));
		datas.assign(2*N, make_pair(INF, false));
		for (int i = 0; i < int(ns.size()); ++i) {
			datas[i+N].first = ns[i];
		}
		for (int i = N - 1 ; i > 0; --i) update(i);
	}

	int getMin(int s, int t) {
		int h = N, k = 0, ans = INF;
		for (;h && (s&h)==(t&h) && (k=(k<<1)|bool((s&h)||h==N)) && k<N; h>>=1) prop(k);

		int i=s?(N+s)/(s&-s):k, sk=k;
		for (int sh = h; sh && (sk=(sk<<1)|bool((s&sh)||sh==N)) < i; sh >>= 1) prop(sk);
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) ans = min(ans, datas[idx].first);;

		int j = s<t?(N+t)/(t&-t)-1:k, tk=k;
		for (int th = h; th && (tk=(tk<<1)|bool((t&th)||th==N)) < j; th >>= 1) prop(tk);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) ans = min(ans, datas[idx].first);

		return ans;
	}

	void fill(int s, int t, int x) {
		int h = N, k = 0;
		for (;h && (s&h)==(t&h) && (k=(k<<1)|bool((s&h)||h==N)) && k<N; h>>=1) prop(k);

		int i=s?(N+s)/(s&-s):k, sk=k;
		for (int sh = h; sh && (sk=(sk<<1)|bool((s&sh)||sh==N)) < i; sh >>= 1) prop(sk);
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) datas[idx] = make_pair(x, true);
		for (;(sk>>=1) > k;) update(sk);

		int j = s<t?(N+t)/(t&-t)-1:k, tk=k;
		for (int th = h; th && (tk=(tk<<1)|bool((t&th)||th==N)) < j; th >>= 1) prop(tk);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) datas[idx] = make_pair(x, true);
		for (;(tk>>=1) > k;) update(tk);

		for (k>>=bool(k>=N); k > 0; k>>=1) update(k);
	}
};

const int MAX_N = int(5e4);
int as[MAX_N], bs[MAX_N], ys[MAX_N], ns[2*MAX_N], ts[MAX_N];

int main() {
	int n; scanf("%d", &n);
	int L = 0;
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d", ts+i, as+i, bs+i, ys+i);
		++bs[i];
		ns[L++] = as[i];
		ns[L++] = bs[i];
	}
	sort(ns, ns + L);
	L = unique(ns, ns+L) - ns;
	for (int i = 0; i < n; ++i) {
		as[i] = lower_bound(ns, ns+L, as[i]) - ns;
		bs[i] = lower_bound(ns, ns+L, bs[i]) - ns;
	}

	SegMax seg(L);
	set<int> ids;
	vector<int> xs(L);
	for (int i = 0; i < L; ++i) {
		ids.insert(i);
	}
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0) {
			seg.fill(as[i], bs[i], ys[i]);
		}
		else {
			for (set<int>::iterator itr = ids.lower_bound(as[i]); itr != ids.end() && *itr < bs[i]; ids.erase(itr++)) {
				xs[*itr] = seg.query(*itr);
			}
		}
	}
	for (set<int>::iterator itr = ids.begin(); itr != ids.end(); ++itr) {
		xs[*itr] = seg.query(*itr);
	}
	SegRMQ rmq(xs);
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0 && rmq.getMin(as[i], bs[i]) != ys[i]) {
			puts("NO");
			return 0;
		}
		else if (ts[i] == 1) {
			rmq.fill(as[i], bs[i], ys[i]);
		}
	}
	puts("YES");

	return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 8132
final_rank: 7

code_snippet: #include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

const int INF = int(1.05e9); 

class SegMax {
	int N;
	vector<int> maxi;
public:
	SegMax(int n) : N(n == 1 ? 1 : 1<<(32 - __builtin_clz(n - 1))), maxi(2*N, 0) {}
	int query(int k) {
		int ans = 0;
		for (k+=N;k>0;k>>=1) ans = max(ans, maxi[k]);
		return ans;
	}
	inline void doit(int k, int x) {maxi[k] = max(maxi[k], x);}
	void fill(int s, int t, int x) {
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) doit(idx, x);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) doit(idx, x);
	}
};

class SegRMQ {
	int N;
	vector<pair<int, bool> > datas;//(mini, uniform)
public:
	SegRMQ(const vector<int>& ns) {
		N = ns.size() == 1 ? 1 : 1<<(32 - __builtin_clz(int(ns.size())-1));
		datas.assign(2*N, make_pair(INF, false));
		for (int i = 0; i < int(ns.size()); ++i) {
			datas[i+N].first = ns[i];
		}
		for (int i = N - 1 ; i > 0; --i) update(i);
	}

	inline void update(int k) {
		datas[k].first = min(datas[2*k].first, datas[2*k+1].first);
	}
	inline void prop(int k) {
		if (datas[k].second) {
			datas[2*k] = datas[2*k+1] = datas[k];
			datas[k].second = false;
		}
	}
	int getMin(int s, int t) {
		int h = N>>1, k = 1, ans = INF;
		prop(k);
		for (;h && (s&h)==(t&h) && (k=(k<<1)|bool(s&h)) && k<N; h>>=1) prop(k);

		int i=s?(N+s)/(s&-s):k, sk=k;
		for (int sh = h; sh && (sk=(sk<<1)|bool(s&sh))  < i; sh >>= 1) prop(sk);
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) ans = min(ans, datas[idx].first);

		int j = s<t?(N+t)/(t&-t)-1:k, tk = k;
		for (int th = h; th && (tk=(tk<<1)|bool(t&th)) < j; th >>= 1) prop(tk);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) ans = min(ans, datas[idx].first);

		return ans;
	}

	void fill(int s, int t, int x) {
		int h = N>>1, k = 1;
		prop(k);
		for (;h && (s&h)==(t&h) && (k=(k<<1)|bool(s&h)) && k<N; h>>=1) prop(k);

		int i=s?(N+s)/(s&-s):k, sk=k;
		for (int sh = h; sh && (sk=(sk<<1)|bool(s&sh))  < i; sh >>= 1) prop(sk);
		for (int idx;0<s && s+(s&-s)<=t && (idx=(N+s)/(s&-s)); s+=s&-s) datas[idx] = make_pair(x, true);
		for (;(sk>>=1) > k;) update(sk);

		int j = s<t?(N+t)/(t&-t)-1:k, tk = k;
		for (int th = h; th && (tk=(tk<<1)|bool(t&th)) < j; th >>= 1) prop(tk);
		for (int idx;s<t && (idx=(N+t)/(t&-t)-1); t-=t&-t) datas[idx] = make_pair(x, true);
		for (;(tk>>=1) > k;) update(tk);

		for (k>>=bool(k>=N); k > 0; k>>=1) update(k);
	}
};

const int MAX_N = int(5e4);
int as[MAX_N], bs[MAX_N], ys[MAX_N], ns[2*MAX_N], ts[MAX_N];

int main() {
	int n; scanf("%d", &n);
	int L = 0;
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d", ts+i, as+i, bs+i, ys+i);
		++bs[i];
		ns[L++] = as[i];
		ns[L++] = bs[i];
	}
	sort(ns, ns + L);
	L = unique(ns, ns+L) - ns;
	for (int i = 0; i < n; ++i) {
		as[i] = lower_bound(ns, ns+L, as[i]) - ns;
		bs[i] = lower_bound(ns, ns+L, bs[i]) - ns;
	}

	SegMax seg(L);
	set<int> ids;
	vector<int> xs(L);
	for (int i = 0; i < L; ++i) {
		ids.insert(i);
	}
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0) {
			seg.fill(as[i], bs[i], ys[i]);
		}
		else {
			set<int>::iterator itr = ids.lower_bound(as[i]);
			for (;itr != ids.end() && *itr < bs[i]; ids.erase(itr++)) {
				xs[*itr] = seg.query(*itr);
			}
		}
	}
	for (set<int>::iterator itr = ids.begin(); itr != ids.end(); ++itr) {
		xs[*itr] = seg.query(*itr);
	}
	SegRMQ rmq(xs);
	for (int i = 0; i < n; ++i) {
		if (ts[i] == 0 && rmq.getMin(as[i], bs[i]) != ys[i]) {
			puts("NO");
			return 0;
		}
		else if (ts[i] == 1) {
			rmq.fill(as[i], bs[i], ys[i]);
		}
	}
	puts("YES");

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 8132
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstdlib>
#include <set>
#include <algorithm>
using namespace std;
#define N (1<<18)

struct Query{
	int t,a,b,y;
};
int Q;
Query que[50000];

set<int> next;

int dead[50000];
vector< pair<int,int> > event[200010];

struct Node{
	int minimum;
	int lazy;
	Node(){ minimum = lazy = 0; }
};

Node seg[2*N];


vector<int> u;
int n;

void update(int l,int r,int v,int k=1,int a=1,int b=N){
	if( seg[k].lazy && k < N ){
		seg[k*2].minimum = seg[k].lazy;
		seg[k*2+1].minimum = seg[k].lazy;
		seg[k*2].lazy = seg[k].lazy;
		seg[k*2+1].lazy = seg[k].lazy;
	}
	seg[k].lazy = 0;
	if( b < l || r < a ) return;
	
	if( l <= a && b <= r ){
		seg[k].minimum = v;
		seg[k].lazy = v;
		return;
	}
	int m = (a+b)>>1;
	update(l,r,v,k*2,a,m);
	update(l,r,v,k*2+1,m+1,b);
	seg[k].minimum = min( seg[k*2].minimum , seg[k*2+1].minimum );
}

int get(int l,int r,int k=1,int a=1,int b=N){
	if( seg[k].lazy && k < N ){
		seg[k*2].minimum = seg[k].lazy;
		seg[k*2+1].minimum = seg[k].lazy;
		seg[k*2].lazy = seg[k].lazy;
		seg[k*2+1].lazy = seg[k].lazy;
	}
	seg[k].lazy = 0;
	if( b < l || r < a ) return 2e9;
	
	if( l <= a && b <= r ){
		return seg[k].minimum;
	}
	int m = (a+b)>>1;
	int vl = get(l,r,k*2,a,m);
	int vr = get(l,r,k*2+1,m+1,b);
	seg[k].minimum = min( seg[k*2].minimum , seg[k*2+1].minimum );
	return min(vl,vr);
}

int seg2[2*N];


void update2(int l,int r,int v,int k=1,int a=1,int b=N){
	if( b < l || r < a ) return;
	
	if( l <= a && b <= r ){
		seg2[k] = max(seg2[k],v);
		return;
	}
	int m = (a+b)>>1;
	update2(l,r,v,k*2,a,m);
	update2(l,r,v,k*2+1,m+1,b);
}


int get2(int i){
	i += N - 1;
	int ans = 0;
	while(i){
		ans = max( ans , seg2[i]);
		i /= 2;
	}
	return ans;
}

int main(){
	scanf("%d",&Q);
	for(int i = 0 ; i < Q ; i++){
		scanf("%d%d%d%d",&que[i].t,&que[i].a,&que[i].b,&que[i].y);
	}
	
	for(int i = 0 ; i < Q ; i++){
		u.push_back(que[i].a);
		u.push_back(que[i].a+1);
		
		u.push_back(que[i].b);
		u.push_back(que[i].b+1);
	}
	u.push_back(0);
	sort(u.begin(),u.end());
	u.erase(unique(u.begin(),u.end()),u.end());
	n = u.size();
	for(int i = 0 ; i < Q ; i++){
		que[i].a = lower_bound(u.begin(),u.end(),que[i].a) - u.begin();
		que[i].b = lower_bound(u.begin(),u.end(),que[i].b) - u.begin();
	}
	
	for(int i = 1 ; i < n ; i++) next.insert(i);
	
	vector<int> arr(n);
	for(int i = 0 ; i < Q ; i++){
		if( que[i].t == 0 ){
			update2(que[i].a,que[i].b,que[i].y);
		}else{
			set<int>::iterator it = next.lower_bound(que[i].a);
			while(it != next.end()){
				if( *it > que[i].b ) break;
				arr[*it] = get2(*it);
				next.erase(it++);
			}
		}
	}
	for(set<int>::iterator it = next.begin(); it != next.end(); ++it){
		arr[*it] = get2(*it);
	}
	
	
	for(int i = 1 ; i < n ; i++) update(i,i,arr[i]);
	//for(int i = 1 ; i < n ; i++) cout << arr[i] << " "; cout << endl;
	for(int i = 0 ; i < Q ; i++){
		if( que[i].t == 0 ){
			if( que[i].y != get(que[i].a,que[i].b) ){	
				cout << "NO" << endl;
				return 0;
			}
		}else{
			update(que[i].a,que[i].b,que[i].y);
		}
	}
	cout << "YES" << endl;
}
accuracy: 1
time_ms: 150
memory_kb: 22740
final_rank: 11

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct Node {
  int lower;
  int upper;
  Node() {;}
  Node(int lower, int upper)
    : lower(lower), upper(upper) {;}
};

inline Node Merge(Node left, Node right) {
  return Node(min(left.lower, right.lower), max(left.upper, right.upper));
}

struct SegmentTree {
  static const int MAX_DEPTH = 18;
  static const int SIZE = 1 << (MAX_DEPTH + 1);  // 2^18 = 262144

  bool updated[SIZE];
  Node data[SIZE];
  SegmentTree() { memset(updated, false, sizeof(updated)); }
  void change(int index, Node value) {
    int target = (1 << MAX_DEPTH) + index;
    data[target] = value;
    for (int i = 1; i <= MAX_DEPTH; i++) {
      target >>= 1;
      data[target] = Merge(data[target * 2], data[target * 2 + 1]);
    }
  }
  void set(Node v, int left, int right) {
    assert(left <= right);
    return in_set(v, 0, 1, left, right);
  }
  Node get(int left, int right) {
    assert(left <= right);
    return in_get(0, 1, left, right);
  }
private:
  void Divide(int node) {
    if (!updated[node] || node >= (1 << MAX_DEPTH)) { return; }
    updated[node] = false;
    updated[node * 2] = true;
    updated[node * 2 + 1] = true;
    data[node * 2] = data[node];
    data[node * 2 + 1] = data[node];
  }
  void in_set(Node v, int depth, int node, int left, int right) {
    int width = 1 << (MAX_DEPTH - depth);
    int index = node - (1 << depth);
    int node_left = index * width;
    int node_mid = node_left + (width >> 1);

    Divide(node);
    if (right - left + 1 == width && left == node_left) {
      updated[node] = true;
      data[node] = v;
    } else {
      if (right < node_mid) {
        in_set(v, depth + 1, node * 2, left, right);
      } else if (left >= node_mid) {
        in_set(v, depth + 1, node * 2 + 1, left, right);
      } else {
        in_set(v, depth + 1, node * 2, left, node_mid - 1);
        in_set(v, depth + 1, node * 2 + 1, node_mid, right);
      }
      data[node] = Merge(data[node * 2], data[node * 2 + 1]);
    }
  }
  Node in_get(int depth, int node, int left, int right) {
    int width = 1 << (MAX_DEPTH - depth);
    int index = node - (1 << depth);
    int node_left = index * width;
    int node_mid = node_left + (width >> 1);

    Divide(node);
    if (right - left + 1 == width && left == node_left) {
      return data[node];
    } else if (right < node_mid) {
      return in_get(depth + 1, node * 2, left, right);
    } else if (left >= node_mid) {
      return in_get(depth + 1, node * 2 + 1, left, right);
    }
    return Merge(in_get(depth + 1, node * 2, left, node_mid - 1), in_get(depth + 1, node * 2 + 1, node_mid, right));
  }
};

enum {
  QUERY_IN,
  QUERY_OUT,
  ASSIGN_IN,
  ASSIGN_OUT
};
struct Event {
  int index;
  int type;
  int x;
  int v;
  Event() {;}
  Event(int index, int type, int x, int v) :
    index(index), type(type), x(x), v(v) {;}
  bool operator<(const Event &rhs) const {
    return x < rhs.x;
  }
};

int t[50010];
int a[50010];
int b[50010];
int y[50010];
int q;
int n, m;
int ini[200010];
SegmentTree stree;
vector<Event> events;

void CalcIni() {
  MEMSET(stree.data, -1);
  int pos = 0;
  set<int> constraints;
  constraints.insert(q);
  set<int> rest;
  REP(i, n) {
    while (pos < (int)events.size() && events[pos].x == i) {
      Event e = events[pos++];
      if (e.type == QUERY_IN) {
        stree.change(e.index, Node(e.v, e.v));
        rest.insert(e.index);
      } else if (e.type == QUERY_OUT) {
        stree.change(e.index, Node(-1, -1));
        rest.erase(e.index);
      } else if (e.type == ASSIGN_IN) {
        constraints.insert(e.index);
      } else if (e.type == ASSIGN_OUT) {
        constraints.erase(e.index);
      }
    }
    ini[i] = stree.get(0, *constraints.begin()).upper;
  }
}

bool Check() {
  stree = SegmentTree();
  MEMSET(stree.data, 1 << 30);
  REP(i, n) { stree.change(i, Node(ini[i], ini[i])); }
  REP(i, q) {
    if (t[i] == 0) {
      if (stree.get(a[i], b[i]).lower != y[i]) { return false; }
    } else {
      stree.set(Node(y[i], y[i]), a[i], b[i]);
    }
  }
  return true;
}

int main() {
  while (scanf("%d", &q) > 0) {
    events.clear();
    n = m = 0;
    {
      set<int> open1;
      set<int> open2;
      REP(i, q) {
        scanf("%d %d %d %d", &t[i], &a[i], &b[i], &y[i]);
        open1.insert(a[i]);
        open1.insert(b[i]);
        open1.insert(b[i] + 1);
        open2.insert(y[i]);
      }
      map<int, int> mapto1;
      map<int, int> mapto2;
      FORIT(it, open1) {
        mapto1[*it] = n++;
      }
      FORIT(it, open2) {
        mapto2[*it] = m++;
      }
      REP(i, q) {
        a[i] = mapto1[a[i]];
        b[i] = mapto1[b[i]];
        y[i] = mapto2[y[i]];
      }
    }
    REP(i, q) {
      events.push_back(Event(i, 2 * t[i], a[i], y[i]));
      events.push_back(Event(i, 2 * t[i] + 1, b[i] + 1, y[i]));
    }
    sort(events.begin(), events.end());
    CalcIni();
    puts(Check() ? "YES" : "NO");
  }
}
accuracy: 1
time_ms: 270
memory_kb: 13000
final_rank: 12

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct Node {
  int lower;
  int upper;
  Node() {;}
  Node(int lower, int upper)
    : lower(lower), upper(upper) {;}
};

inline Node Merge(Node left, Node right) {
  return Node(min(left.lower, right.lower), max(left.upper, right.upper));
}

struct SegmentTree {
  static const int MAX_DEPTH = 18;
  static const int SIZE = 1 << (MAX_DEPTH + 1);  // 2^18 = 262144

  bool updated[SIZE];
  Node data[SIZE];
  SegmentTree() { memset(updated, false, sizeof(updated)); }
  void change(int index, Node value) {
    int target = (1 << MAX_DEPTH) + index;
    data[target] = value;
    for (int i = 1; i <= MAX_DEPTH; i++) {
      target >>= 1;
      data[target] = Merge(data[target * 2], data[target * 2 + 1]);
    }
  }
  void set(Node v, int left, int right) {
    assert(left <= right);
    return in_set(v, 0, 1, left, right);
  }
  Node get(int left, int right) {
    assert(left <= right);
    return in_get(0, 1, left, right);
  }
private:
  void Divide(int node) {
    if (!updated[node] || node >= (1 << MAX_DEPTH)) { return; }
    updated[node] = false;
    updated[node * 2] = true;
    updated[node * 2 + 1] = true;
    data[node * 2] = data[node];
    data[node * 2 + 1] = data[node];
  }
  void in_set(Node v, int depth, int node, int left, int right) {
    int width = 1 << (MAX_DEPTH - depth);
    int index = node - (1 << depth);
    int node_left = index * width;
    int node_mid = node_left + (width >> 1);

    Divide(node);
    if (right - left + 1 == width && left == node_left) {
      updated[node] = true;
      data[node] = v;
    } else if (right < node_mid) {
      in_set(v, depth + 1, node * 2, left, right);
      data[node] = Merge(data[node * 2], data[node * 2 + 1]);
    } else if (left >= node_mid) {
      in_set(v, depth + 1, node * 2 + 1, left, right);
      data[node] = Merge(data[node * 2], data[node * 2 + 1]);
    } else {
      in_set(v, depth + 1, node * 2, left, node_mid - 1);
      in_set(v, depth + 1, node * 2 + 1, node_mid, right);
      data[node] = Merge(data[node * 2], data[node * 2 + 1]);
    }
  }
  Node in_get(int depth, int node, int left, int right) {
    int width = 1 << (MAX_DEPTH - depth);
    int index = node - (1 << depth);
    int node_left = index * width;
    int node_mid = node_left + (width >> 1);

    Divide(node);
    if (right - left + 1 == width && left == node_left) {
      return data[node];
    } else if (right < node_mid) {
      return in_get(depth + 1, node * 2, left, right);
    } else if (left >= node_mid) {
      return in_get(depth + 1, node * 2 + 1, left, right);
    }
    return Merge(in_get(depth + 1, node * 2, left, node_mid - 1), in_get(depth + 1, node * 2 + 1, node_mid, right));
  }
};

enum {
  QUERY_IN,
  QUERY_OUT,
  ASSIGN_IN,
  ASSIGN_OUT
};
struct Event {
  int index;
  int type;
  int x;
  int v;
  Event() {;}
  Event(int index, int type, int x, int v) :
    index(index), type(type), x(x), v(v) {;}
  bool operator<(const Event &rhs) const {
    return x < rhs.x;
  }
};

int t[50010];
int a[50010];
int b[50010];
int y[50010];
int q;
int n, m;
int ini[100010];
SegmentTree stree;
vector<Event> events;

void CalcIni() {
  MEMSET(stree.data, 0);
  int pos = 0;
  set<int> constraints;
  constraints.insert(q);
  REP(i, n) {
    while (pos < q * 2 && events[pos].x == i) {
      Event e = events[pos++];
      if (e.type == QUERY_IN) {
        stree.change(e.index, Node(e.v, e.v));
      } else if (e.type == QUERY_OUT) {
        stree.change(e.index, Node(0, 0));
      } else if (e.type == ASSIGN_IN) {
        constraints.insert(e.index);
      } else if (e.type == ASSIGN_OUT) {
        constraints.erase(e.index);
      }
    }
    ini[i] = stree.get(0, *constraints.begin()).upper;
  }
}

bool Check() {
  REP(i, n) { stree.change(i, Node(ini[i], ini[i])); }
  REP(i, q) {
    if (t[i] == 0) {
      if (stree.get(a[i], b[i]).lower != y[i]) { return false; }
    } else {
      stree.set(Node(y[i], y[i]), a[i], b[i]);
    }
  }
  return true;
}

int main() {
  while (scanf("%d", &q) > 0) {
    events.clear();
    n = m = 0;
    {
      set<int> open1;
      set<int> open2;
      REP(i, q) {
        scanf("%d %d %d %d", &t[i], &a[i], &b[i], &y[i]);
        open1.insert(a[i]);
        open1.insert(b[i]);
        open1.insert(b[i] + 1);
        open2.insert(y[i]);
      }
      map<int, int> mapto1;
      map<int, int> mapto2;
      FORIT(it, open1) {
        mapto1[*it] = n++;
      }
      FORIT(it, open2) {
        mapto2[*it] = m++;
      }
      REP(i, q) {
        a[i] = mapto1[a[i]];
        b[i] = mapto1[b[i]];
        y[i] = mapto2[y[i]];
      }
    }
    REP(i, q) {
      events.push_back(Event(i, 2 * t[i], a[i], y[i]));
      events.push_back(Event(i, 2 * t[i] + 1, b[i] + 1, y[i]));
    }
    sort(events.begin(), events.end());
    CalcIni();
    puts(Check() ? "YES" : "NO");
  }
}
accuracy: 0.25925925925925924
time_ms: 220
memory_kb: 11000
final_rank: 20

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct Node {
  int lower;
  int upper;
  Node() {;}
  Node(int lower, int upper)
    : lower(lower), upper(upper) {;}
};

inline Node Merge(Node left, Node right) {
  return Node(min(left.lower, right.lower), max(left.upper, right.upper));
}

struct SegmentTree {
  static const int MAX_DEPTH = 17;
  static const int SIZE = 1 << (MAX_DEPTH + 1);  // 2^18 = 262144

  bool updated[SIZE];
  Node data[SIZE];
  SegmentTree() { memset(updated, false, sizeof(updated)); }
  void change(int index, Node value) {
    int target = (1 << MAX_DEPTH) + index;
    data[target] = value;
    for (int i = 1; i <= MAX_DEPTH; i++) {
      target >>= 1;
      data[target] = Merge(data[target * 2], data[target * 2 + 1]);
    }
  }
  void set(Node v, int left, int right) {
    assert(left <= right);
    return in_set(v, 0, 1, left, right);
  }
  Node get(int left, int right) {
    assert(left <= right);
    return in_get(0, 1, left, right);
  }
private:
  void Divide(int node) {
    if (!updated[node] || node >= (1 << MAX_DEPTH)) { return; }
    updated[node] = false;
    updated[node * 2] = true;
    updated[node * 2 + 1] = true;
    data[node * 2] = data[node];
    data[node * 2 + 1] = data[node];
  }
  void in_set(Node v, int depth, int node, int left, int right) {
    int width = 1 << (MAX_DEPTH - depth);
    int index = node - (1 << depth);
    int node_left = index * width;
    int node_mid = node_left + (width >> 1);

    Divide(node);
    if (right - left + 1 == width && left == node_left) {
      updated[node] = true;
      data[node] = v;
    } else if (right < node_mid) {
      in_set(v, depth + 1, node * 2, left, right);
      data[node] = Merge(data[node * 2], data[node * 2 + 1]);
    } else if (left >= node_mid) {
      in_set(v, depth + 1, node * 2 + 1, left, right);
      data[node] = Merge(data[node * 2], data[node * 2 + 1]);
    } else {
      in_set(v, depth + 1, node * 2, left, node_mid - 1);
      in_set(v, depth + 1, node * 2 + 1, node_mid, right);
      data[node] = Merge(data[node * 2], data[node * 2 + 1]);
    }
  }
  Node in_get(int depth, int node, int left, int right) {
    int width = 1 << (MAX_DEPTH - depth);
    int index = node - (1 << depth);
    int node_left = index * width;
    int node_mid = node_left + (width >> 1);

    Divide(node);
    if (right - left + 1 == width && left == node_left) {
      return data[node];
    } else if (right < node_mid) {
      return in_get(depth + 1, node * 2, left, right);
    } else if (left >= node_mid) {
      return in_get(depth + 1, node * 2 + 1, left, right);
    }
    return Merge(in_get(depth + 1, node * 2, left, node_mid - 1), in_get(depth + 1, node * 2 + 1, node_mid, right));
  }
};

enum {
  QUERY_IN,
  QUERY_OUT,
  ASSIGN_IN,
  ASSIGN_OUT
};
struct Event {
  int index;
  int type;
  int x;
  int v;
  Event() {;}
  Event(int index, int type, int x, int v) :
    index(index), type(type), x(x), v(v) {;}
  bool operator<(const Event &rhs) const {
    return x < rhs.x;
  }
};

int t[50010];
int a[50010];
int b[50010];
int y[50010];
int q;
int n, m;
int ini[100010];
SegmentTree stree;
vector<Event> events;

void CalcIni() {
  MEMSET(stree.data, 0);
  int pos = 0;
  set<int> constraints;
  constraints.insert(q);
  REP(i, n) {
    while (pos < q * 2 && events[pos].x == i) {
      Event e = events[pos++];
      if (e.type == QUERY_IN) {
        stree.change(e.index, Node(e.v, e.v));
      } else if (e.type == QUERY_OUT) {
        stree.change(e.index, Node(0, 0));
      } else if (e.type == ASSIGN_IN) {
        constraints.insert(e.index);
      } else if (e.type == ASSIGN_OUT) {
        constraints.erase(e.index);
      }
    }
    ini[i] = stree.get(0, *constraints.begin()).upper;
  }
}

bool Check() {
  REP(i, n) { stree.change(i, Node(ini[i], ini[i])); }
  REP(i, q) {
    if (t[i] == 0) {
      if (stree.get(a[i], b[i]).lower != y[i]) { return false; }
    } else {
      stree.set(Node(y[i], y[i]), a[i], b[i]);
    }
  }
  return true;
}

int main() {
  while (scanf("%d", &q) > 0) {
    events.clear();
    n = m = 0;
    {
      set<int> open1;
      set<int> open2;
      REP(i, q) {
        scanf("%d %d %d %d", &t[i], &a[i], &b[i], &y[i]);
        open1.insert(a[i]);
        open1.insert(b[i]);
        open1.insert(b[i] + 1);
        open2.insert(y[i]);
      }
      map<int, int> mapto1;
      map<int, int> mapto2;
      FORIT(it, open1) {
        mapto1[*it] = n++;
      }
      FORIT(it, open2) {
        mapto2[*it] = m++;
      }
      REP(i, q) {
        a[i] = mapto1[a[i]];
        b[i] = mapto1[b[i]];
        y[i] = mapto2[y[i]];
      }
    }
    REP(i, q) {
      events.push_back(Event(i, 2 * t[i], a[i], y[i]));
      events.push_back(Event(i, 2 * t[i] + 1, b[i] + 1, y[i]));
    }
    sort(events.begin(), events.end());
    CalcIni();
    puts(Check() ? "YES" : "NO");
  }
}
accuracy: 0.25925925925925924
time_ms: 220
memory_kb: 0
final_rank: 19

code_snippet: #include<iostream>
#include<sstream>
#include<vector>
#include<algorithm>
#include<map>
#include<queue>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
using namespace std;

#define rep(i,n) for(int i=0;i<(int)n;i++)
#define fr(i,c) for(__typeof(c.begin()) i=c.begin();i!=c.end();i++)
#define pb push_back
#define mp make_pair
#define all(c) c.begin(),c.end()
#define dbg(x) cerr<<#x<<" = "<<(x)<<endl

typedef vector<int> vi;
typedef pair<int,int> pi;
typedef long long ll;
const int inf=(int)1e9;
const double EPS=1e-9, INF=1e12;

const int sz=256, MX=60000;
int q,t[MX],a[MX],b[MX],y[MX];
int vs[MX*2],init[MX*2],m;
int z[MX*2],mx[1000];
bool eq[1000],initialized[1000];

inline void takemax(int i,int j,int x){
	bool flag=eq[i/sz];
	while(i<j&&i%sz){
		if(eq[i/sz])rep(k,sz)z[i/sz*sz+k]=mx[i/sz];
		eq[i/sz]=0; z[i]=max(flag?mx[i/sz]:z[i],x);
		i++;
	}
	flag=eq[(j-1)/sz];
	while(i<j&&j%sz){
		if(eq[--j/sz])rep(k,sz)z[j/sz*sz+k]=mx[j/sz];
		eq[j/sz]=0; z[j]=max(flag?mx[j/sz]:z[j],x);
	}
	i/=sz; j/=sz;
	if(i&&!eq[i-1]){
		mx[i-1]=inf;
		rep(k,sz)mx[i-1]=min(mx[i-1],z[(i-1)*sz+k]);
	}
	if(!eq[j]){
		mx[j]=inf;
		rep(k,sz)mx[j]=min(mx[j],z[j*sz+k]);
	}
	while(i<j){
		if(eq[i]||mx[i]>=x)mx[i]=max(mx[i],x);
		else{
			mx[i]=inf;
			rep(k,sz)z[i*sz+k]=max(z[i*sz+k],x), mx[i]=min(mx[i],z[i*sz+k]);
		}
		i++;
	}
}
inline void set(int i,int j,int x,bool ini=0){
	bool flag=eq[i/sz];
	while(i<j&&i%sz){
		if(ini&&!initialized[i/sz]&&init[i]==-inf)init[i]=flag?mx[i/sz]:z[i];
		if(eq[i/sz])rep(k,sz)z[i/sz*sz+k]=mx[i/sz];
		eq[i/sz]=0; z[i++]=x;
	}
	flag=eq[(j-1)/sz];
	while(i<j&&j%sz){
		j--;
		if(ini&&!initialized[j/sz]&&init[j]==-inf)init[j]=flag?mx[j/sz]:z[j];
		if(eq[j/sz])rep(k,sz)z[j/sz*sz+k]=mx[j/sz];
		eq[j/sz]=0; z[j]=x;
	}
	i/=sz; j/=sz;
	if(i&&!eq[i-1]){
		mx[i-1]=inf;
		rep(k,sz)mx[i-1]=min(mx[i-1],z[(i-1)*sz+k]);
	}
	if(!eq[j]){
		mx[j]=inf;
		rep(k,sz)mx[j]=min(mx[j],z[j*sz+k]);
	}
	while(i<j){
		if(ini&&!initialized[i]){
			rep(k,sz)if(init[i*sz+k]==-inf)init[i*sz+k]=eq[i]?mx[i]:z[i*sz+k];
			initialized[i]=1;
		}
		eq[i]=1; mx[i++]=x;
	}
}
inline int get(int i,int j){
	int res=inf;
	while(i<j&&i%sz)res=min(res,eq[i/sz]?mx[i/sz]:z[i]), i++;
	while(i<j&&j%sz)res=min(res,eq[--j/sz]?mx[j/sz]:z[j]);
	i/=sz; j/=sz;
	while(i<j)res=min(res,mx[i++]);
	return res;
}

bool func(bool ck){
	rep(i,q){
		if(t[i]==0){
			if(!ck)takemax(a[i],b[i],y[i]);
 			else if(get(a[i],b[i])!=y[i]) return 0;
		}
		else set(a[i],b[i],y[i],!ck);
	}
	if(!ck)rep(i,m)if(init[i]==-inf)init[i]=eq[i/sz]?mx[i/sz]:z[i];
	return 1;
}

int main(){
	scanf("%d",&q);
	rep(i,q){
		scanf("%d%d%d%d",t+i,a+i,b+i,y+i);
		vs[2*i]=a[i]; vs[2*i+1]=++b[i];
	}
	sort(vs,vs+2*q);
	m=unique(vs,vs+2*q)-vs;
	rep(i,q){
		a[i]=lower_bound(vs,vs+m,a[i])-vs;
		b[i]=lower_bound(vs,vs+m,b[i])-vs;
	}
	
	rep(i,m)z[i]=init[i]=-inf;
	rep(i,(m+sz-1)/sz)mx[i]=-inf, eq[i]=1;
	func(0);
	rep(i,m)z[i]=init[i];
	rep(i,(m+sz-1)/sz){
		eq[i]=1; mx[i]=inf;
		rep(j,sz)if(i*sz+j<m){
			mx[i]=min(mx[i],z[i*sz+j]);
			if(z[i*sz]!=z[i*sz+j])eq[i]=0;
		}
	}
	puts(func(1)?"YES":"NO");
	
	return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 2828
final_rank: 9