답안 #408642

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
408642 2021-05-19T12:03:11 Z codebuster_10 Growing Trees (BOI11_grow) C++17
10 / 100
151 ms 11732 KB
#include <bits/stdc++.h>

using namespace std ;

#define int int64_t //be careful about this 
#define endl "\n"
#define f(i,a,b) for(int i=int(a);i<int(b);++i)

#define pr pair
#define ar array
#define fr first
#define sc second
#define vt vector
#define pb push_back
#define eb emplace_back
#define LB lower_bound  
#define UB upper_bound
#define PQ priority_queue

#define sz(x) ((int)(x).size())
#define all(a) (a).begin(),(a).end()
#define allr(a) (a).rbegin(),(a).rend()
#define mem0(a) memset(a, 0, sizeof(a))
#define mem1(a) memset(a, -1, sizeof(a))

template<class A> void rd(vt<A>& v);
template<class T> void rd(T& x){ cin >> x; }
template<class H, class... T> void rd(H& h, T&... t) { rd(h) ; rd(t...) ;}
template<class A> void rd(vt<A>& x) { for(auto& a : x) rd(a) ;}

template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }

template<typename T>
void __p(T a) {
  cout<<a; 
}
template<typename T, typename F>
void __p(pair<T, F> a) {
  cout<<"{";
  __p(a.first);
  cout<<",";
  __p(a.second);
  cout<<"}\n"; 
}
template<typename T>
void __p(std::vector<T> a) {
  cout<<"{";
  for(auto it=a.begin(); it<a.end(); it++)
    __p(*it),cout<<",}\n"[it+1==a.end()]; 
}
template<typename T, typename ...Arg>
void __p(T a1, Arg ...a) {
  __p(a1);
  __p(a...);
}
template<typename Arg1>
void __f(const char *name, Arg1 &&arg1) {
  cout<<name<<" : ";
  __p(arg1);
  cout<<endl;
}
template<typename Arg1, typename ... Args>
void __f(const char *names, Arg1 &&arg1, Args &&... args) {
  int bracket=0,i=0;
  for(;; i++)
    if(names[i]==','&&bracket==0)
      break;
    else if(names[i]=='(')
      bracket++;
    else if(names[i]==')')
      bracket--;
  const char *comma=names+i;
  cout.write(names,comma-names)<<" : ";
  __p(arg1);
  cout<<" | ";
  __f(comma+1,args...);
}

void setIO(string s = "") {
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); 
  cin.exceptions(cin.failbit); 
	cout.precision(15);	cout << fixed;
  #ifdef ONLINE_JUDGE
  if(sz(s)){
  	freopen((s+".in").c_str(),"r",stdin);
  	freopen((s+".out").c_str(),"w",stdout);
  }
  #define __f(...) 0
  #endif
}


/* 
  * Description segment tree for mass changes using lazy propagation
  * source: pashka edu course with very little own modifications 
  * verify commutivity and distributivity property for changes, assignement ans sum do not follow these property
  * set ID, NEUTRAL_ELEMENT, NO_OPERATION accordingly.
  * update on interval [l, r) and query val at range [l, r)
  * change x tells that at x this change is done but have to propogate to children
  * verification :- https://codeforces.com/edu/course/2/lesson/5/2/practice/status
*/

template<class T, class H> struct lazy_segment_tree { 
	const T ID = 0, NEUTRAL_ELEMENT = 0;
  const H NO_OPERATION = 0;
  int size ;
  vector<T> segment_tree;
  vector<H> change;

  void apply_lazy_on_change(H &a, H b){ 
    a += b;
  }  

  T combiner_function(T a, T b){  
    return max(a,b);
  }

  void apply_lazy_on_node(T &a, H b){
    a += b;
  }
    
  void propogate(int x, int lx, int rx){
    if(rx - lx == 1) return ;
    apply_lazy_on_node(segment_tree[2 * x + 1], change[x]); 
    apply_lazy_on_node(segment_tree[2 * x + 2], change[x]);
    apply_lazy_on_change(change[2 * x + 1], change[x]);
    apply_lazy_on_change(change[2 * x + 2], change[x]);
    change[x] = NO_OPERATION;
  }
  
  void init(int n){ 
    size = 1;
    while(size < n) size *= 2;
    segment_tree.assign(2*size, ID); 
		change.assign(2*size, NO_OPERATION); 
  }
  
  void build(const vector<T> &initial){
  	int _size = int(initial.size());
  	init(_size);
  	assert(_size <= size);
  	build(0, 0, size, initial, _size);
  }
  void build(int x, int lx, int rx, const vector<T> &initial, int _size){
  	if(rx - lx == 1){
  		if(x >= size - 1 && x - size + 1 < _size){
  			segment_tree[x] = initial[x - size + 1];
  		}else{
  			segment_tree[x] = ID;
  		}
  	}else{
  		int mid = (lx + rx)/2;
  		build(2 * x + 1, lx, mid, initial, _size);
  		build(2 * x + 2, mid, rx, initial, _size);
  		segment_tree[x] = combiner_function(segment_tree[2 * x + 1], segment_tree[2 * x + 2]);
  	}
  }
  
	void update(int l, int r, int x, int lx, int rx, H value) { 
    propogate(x, lx, rx) ;
    if( lx >= r || l >= rx ){
      return;
    }
    if( lx >= l && rx <= r){
      apply_lazy_on_node(segment_tree[x], value);
      apply_lazy_on_change(change[x], value);  
      return ;
    }
    int mid = (rx + lx)/2 ;
  	update(l, r, 2 * x + 1, lx, mid, value); 
		update(l, r, 2 * x + 2, mid, rx, value); 
		segment_tree[x] = combiner_function(segment_tree[2 * x + 1], segment_tree[2 * x + 2]) ;
		return ;
  }
  
  void update(int l, int r, H value) { 
    update(l, r, 0, 0, size, value) ; return ;
  }
  
  int query(int val, int x, int lx, int rx) { 
    propogate(x, lx, rx);
    if(rx - lx == 1){
    	assert(segment_tree[x] >= val);
    	return x - size + 1; 
    }
    int mid = (rx + lx)/2 ;
    if(segment_tree[2 * x + 1] >= val){
      return query(val, 2 * x + 1, lx, mid);
    }else{
    	return query(val, 2 * x + 2, mid, rx);
    }
  }
  
	int query(int val) { 
		if(segment_tree[0] < val) return -1;
    return query(val, 0, 0, size) ;
  }
  
  T query(int l, int r, int x, int lx, int rx) { 
    propogate(x, lx, rx) ;
    if( lx >= r || l >= rx ){
      return NEUTRAL_ELEMENT;
    }
    if( lx >= l && rx <= r){
      return segment_tree[x] ;
    }
    int mid = (rx + lx)/2 ;
		return combiner_function(query(l, r, 2 * x + 1, lx, mid), query(l, r, 2 * x + 2, mid, rx)) ;
  }
  
	T query(int l, int r) { 
    return query(l, r, 0, 0, size) ;
  }
  
};

signed main(){
  setIO() ;
  int n,m; rd(n,m);
  vt<int> a(n);
  rd(a);
  sort(all(a));
  lazy_segment_tree<int,int> st;
  st.build(a);
	while(m--){
		char _c; rd(_c);
		if(_c == 'C'){
			int a,b; rd(a,b);
			int l = st.query(a);
			int r = st.query(b+1);
			if(l == -1 || r == 0){
				cout << 0 << endl; continue;
			}
			if(r == -1) r = n;
			cout << r - l << endl;
		}else{
			int c,h; rd(c,h);
			int i = st.query(h);
			if(i == -1) continue;
			if(i + c - 1 >= n - 1){
				st.update(i,n,1); continue;
			}
			int x = st.query(i+c-1,i+c);
			int first = st.query(x);
			int last = st.query(x+1) - 1;
			assert(first <= last);
			st.update(i,first,1);
			c -= (first - i);
			st.update(last-c+1,last+1,1); 
		}
	}  
}













# 결과 실행 시간 메모리 Grader output
1 Runtime error 23 ms 10700 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 332 KB Output is correct
2 Runtime error 2 ms 588 KB Execution killed with signal 6
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 5 ms 1288 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 3 ms 1228 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 19 ms 6208 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 28 ms 10376 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 19 ms 10436 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 151 ms 11732 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 28 ms 10704 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 125 ms 7472 KB Output is correct