Submission #635642

#TimeUsernameProblemLanguageResultExecution timeMemory
635642welleythAbracadabra (CEOI22_abracadabra)C++17
35 / 100
3038 ms37088 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> //#define int long long #define mp make_pair #define pb push_back using namespace std; using namespace __gnu_pbds; mt19937 rnd(time(nullptr)); constexpr int N = (int)1e6 + 111; int tr[N]; int SUM = 0; void upd(int r,int x){ SUM += x; for(int i = r; i < N; i |= i+1) tr[i] += x; return; } int get(int r){ int s = 0; for(int i = r; i >= 0; i&=i+1,i--) s += tr[i]; return s; } int getSuf(int r){ return SUM - get(r-1); } int a[N]; int t[N],P[N]; int n = 20,q = 20; vector<int> brute(){ int b[n]; vector<int> ans; int A[n+1][n]; for(int i = 0; i < n; i++){ A[0][i] = a[i]; b[i] = a[i]; } int cnt = 0; for(int i = 1;; i++){ int ptr[2] = {0,n/2}; int pos = 0; while(ptr[0] < n/2 && ptr[1] < n){ if(A[i-1][ptr[0]] < A[i-1][ptr[1]]){ A[i][pos++] = A[i-1][ptr[0]++]; } else { A[i][pos++] = A[i-1][ptr[1]++]; } } while(ptr[0] < n/2) A[i][pos++] = A[i-1][ptr[0]++]; while(ptr[1] < n) A[i][pos++] = A[i-1][ptr[1]++]; bool diff = false; for(int j = 0; j < n; j++){ diff |= A[i-1][j] != A[i][j]; } cnt++; if(!diff) break; } for(int i = 0; i < q; i++){ t[i] = min(t[i],cnt); ans.pb(A[t[i]][P[i]-1]); } return ans; } tree<pair<int,int>,null_type,less<pair<int,int>>,rb_tree_tag,tree_order_statistics_node_update> st; int parent[N]; vector<pair<int,pair<int,int>>> Q; int ans[N]; void __attribute__ (( optimize("Ofast","unroll-loops"), target("avx2") )) solve(){ n = (int)10000, q = (int)10000; for(int i = 0; i <= n; i++) tr[i] = 0; st.clear(); SUM = 0; Q.clear(); cin >> n >> q; int rv[n+1]; for(int i = 0; i < n; i++){ cin >> a[i]; rv[a[i]] = i; } int nxt[n+1]; vector<pair<int,int>> RightBiggest; for(int i = n-1; i >= 0; i--){ while(!RightBiggest.empty() && RightBiggest.back().first < a[i]) RightBiggest.pop_back(); if(!RightBiggest.empty()) nxt[i] = RightBiggest.back().second; else nxt[i] = n; RightBiggest.pb(mp(a[i],i)); } for(int i = 0; i < q; i++){ cin >> t[i] >> P[i]; Q.pb(mp(t[i],mp(P[i],i))); } sort(Q.begin(),Q.end()); vector<pair<int,int>> v; bool used[n+1]; for(int i = 0; i <= n; i++){ used[i] = false; } for(int i = 0; i < n; i++){ if(used[i]) continue; int __r = nxt[i]; if(i < n/2) __r = min(__r,n/2); for(int j = i; j < __r; j++) used[j] = 1; st.insert(mp(a[i],__r-i)); upd(a[i],__r-i); } // cout << "st:\n"; // for(auto&[x,y] : st){ // cout << x << " " << y << "\n"; // } int cur_t = 1; bool all = false; for(auto& query : Q){ int& t = query.first; int& pos = query.second.first; int& id = query.second.second; if(t == 0){ ans[id] = a[pos-1]; continue; } while(!all && cur_t < t){ int l = 0, r = st.size(); while(r - l > 1){ int m = (l+r)>>1; int x = st.find_by_order(m)->first; int tl = getSuf(x); if(tl > n/2) l = m; else r = m; } int x = st.find_by_order(l)->first; int y = st.find_by_order(l+1)->first; int tr = getSuf(y); if(n/2 - tr <= 0){ all = true; break; } int delta = n/2 - tr; int __len = st.find_by_order(l)->second; int __pos = rv[x] + __len - delta; upd(x,-delta); st.erase(mp(x,__len)); st.insert(mp(x,__len-delta)); while(__pos < rv[x] + __len){ int __r = min(nxt[__pos],rv[x] + __len); st.insert(mp(a[__pos],__r - __pos)); upd(a[__pos],__r-__pos); __pos = __r; } cur_t++; } int l = 0, r = st.size(); while(r - l > 1){ int m = (l+r)>>1; int x = st.find_by_order(m)->first; if(getSuf(x) >= n - pos + 1) l = m; else r = m; } int x = st.find_by_order(l)->first; int sz = st.find_by_order(l)->second; int suffSum = 0; if(l + 1 != st.size()){ int y = st.find_by_order(l+1)->first; suffSum = getSuf(y); } int cur_pos = (n - pos + 1) - suffSum; // cerr << "suffSum = " << suffSum << "\n"; cur_pos = sz - cur_pos; int __pos = rv[x]; // cerr << x << " " << sz << "\n"; // cerr << "__pos = " << __pos << "\n"; // cerr << "cur_pos = " << cur_pos << "\n"; ans[id] = a[__pos + cur_pos]; // cerr << "st:\n"; // for(auto&[x,y] : st){ // cerr << x << " " << y << "\n"; // } } for(int i = 0; i < q; i++){ cout << ans[i] << "\n"; } return; } signed main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int tests = 1; // cin >> tests; for(int test = 1; test <= tests; test++){ solve(); } return 0; } /** 6 1 2 1 5 4 6 3 1 1 2 1 4 5 6 3 6 1 1 5 6 2 3 4 1 2 10 1 7 5 2 9 10 8 4 3 6 1 3 4 7 5 2 || 8 4 3 6 1 || 9 || 10 3 || 6 1 || 7 5 2 || 8 4 || 9 || 10 2 || 3 || 6 1 || 7 5 || 8 4 || 9 || 10 **/

Compilation message (stderr)

Main.cpp: In function 'std::vector<int> brute()':
Main.cpp:37:9: warning: variable 'b' set but not used [-Wunused-but-set-variable]
   37 |     int b[n];
      |         ^
Main.cpp: In function 'void solve()':
Main.cpp:178:18: warning: comparison of integer expressions of different signedness: 'int' and '__gnu_pbds::detail::bin_search_tree_set<std::pair<int, int>, __gnu_pbds::null_type, std::less<std::pair<int, int> >, __gnu_pbds::detail::tree_traits<std::pair<int, int>, __gnu_pbds::null_type, std::less<std::pair<int, int> >, __gnu_pbds::tree_order_statistics_node_update, __gnu_pbds::rb_tree_tag, std::allocator<char> >, std::allocator<char> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  178 |         if(l + 1 != st.size()){
      |            ~~~~~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...