제출 #409243

#제출 시각아이디문제언어결과실행 시간메모리
409243codebuster_10Bubble Sort 2 (JOI18_bubblesort2)C++17
100 / 100
4500 ms85608 KiB
#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
*/

const int inf = 1e9;
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 - 1, ID); 
		change.assign(2*size - 1, 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 ;
  }
  
  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) ;
  }
};

const int LOG = 25;
#undef int 
std::vector<int> countScans(std::vector<int> A,std::vector<int> X,std::vector<int> V){
#define int int64_t
  setIO() ;
  int n = sz(A), q = sz(X); 
  vt<int> a(n);
  f(i,0,n) a[i] = A[i];
  vt<pr<int,int>> query(q);
  f(i,0,q){
  	query[i] = {X[i],V[i]};
  }
  
  vt<int> comp;
  f(i,0,n){
  	comp.pb((a[i]<<(int)LOG) + i);
  }
  for(auto& [i,x]:query){
  	comp.pb((x<<(int)LOG) + i);
  }
  sort(all(comp));
  comp.erase(unique(all(comp)),comp.end());
  int m = sz(comp);
  
  lazy_segment_tree<int,int> st;
  st.init(m);
  
  auto add = [&](int i){
  	int j = lower_bound(all(comp),(a[i]<<(int)LOG) + i) - comp.begin();
		//assert(comp[j] == (a[i]<<(int)LOG) + i);
  	st.update(j+1,m+1,-1);
  	st.update(j,j+1,i);
  };
  auto rem = [&](int i){
  	int j = lower_bound(all(comp),(a[i]<<(int)LOG) + i) - comp.begin();
		//assert(comp[j] == (a[i]<<(int)LOG) + i);
  	st.update(j+1,m+1,1);
  	st.update(j,j+1,-i);
  };
  
  f(i,0,n) add(i);
  vt<int> ans;
  for(auto [i,x]:query){
  	rem(i);
  	a[i] = x;
  	add(i);
  	ans.pb(st.query(0,m+1));
  }
#undef int 
	vt<int> _ans(q);
	f(i,0,q) _ans[i] = ans[i];
	return _ans; 
}

/*
#include <cstdio>
#include <cstdlib>
#include <vector>

int readInt(){
	int i;
	if(scanf("%d",&i)!=1){
		fprintf(stderr,"Error while reading input\n");
		exit(1);
	}
	return i;
}

int main(){
	int N,Q;
	N=readInt();
	Q=readInt();
	
	std::vector<int> A(N);
	for(int i=0;i<N;i++)
		A[i]=readInt();
	
	std::vector<int> X(Q),V(Q);
	for(int j=0;j<Q;j++){
		X[j]=readInt();
		V[j]=readInt();
	}
	
	std::vector<int> res=countScans(A,X,V);
	
	for(int j=0;j<int(res.size());j++)
		printf("%d\n",res[j]);
}

*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...