Submission #241570

#TimeUsernameProblemLanguageResultExecution timeMemory
241570abacabaHoliday (IOI14_holiday)C++14
100 / 100
1911 ms8856 KiB
#include <iostream> #include <string> #include <unordered_map> #include <unordered_set> #include <cstring> #include <chrono> #include <vector> #include <map> #include <random> #include <set> #include <algorithm> #include <math.h> #include <cstdio> #include <stdio.h> #include <queue> #include <bitset> #include <cstdlib> #include <deque> #include <cassert> #include <stack> using namespace std; #define mp make_pair #define f first #define se second #define pb push_back #define ppb pop_back #define emb emplace_back #define ll long long #define ull unsigned long long #define cntbit(x) __builtin_popcount(x) #define endl '\n' #define uset unordered_set #define umap unordered_map #define pii pair<int, int> #define ld long double #define pll pair<long long, long long> mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); template <typename T> inline T range(T l, T r) { return uniform_int_distribution<T>(l, r)(rng); } inline void setin(string s) { freopen(s.c_str(), "r", stdin); } inline void setout(string s) { freopen(s.c_str(), "w", stdout); } template <typename T> void Min(T &a, T b) { a = min(a, b); } template <typename T> void Max(T &a, T b) { a = max(a, b); } const int inf = 1e9; const int mod = 998244353; const int D = 3e5 + 15; const int N = 1e5 + 5; int a[N]; vector <int> comp; pair <ll, int> f[D], g[D]; bool used[N]; struct segment_tree { ll sum[N << 2]; int cnt[N << 2]; segment_tree() { memset(sum, 0, sizeof(sum)); memset(cnt, 0, sizeof(cnt)); } void update(int v, int tl, int tr, int pos, int val) { cnt[v] += val, sum[v] += comp[pos - 1] * val; if(tl != tr) { int mid = tl + tr >> 1; if(pos <= mid) update(v << 1, tl, mid, pos, val); else update(v << 1 | 1, mid + 1, tr, pos, val); } } inline ll get_sum_of_k(int v, int tl, int tr, int k) { if(k <= 0) return 0; int cur_cnt = cnt[v]; if(cur_cnt <= k) return sum[v]; if(tl == tr) return 1LL * k * comp[tl - 1]; int mid = tl + tr >> 1; int cntr = cnt[v << 1 | 1]; return get_sum_of_k(v << 1, tl, mid, k - cntr) + get_sum_of_k(v << 1 | 1, mid + 1, tr, k); } } t; inline int gt(int x) { return lower_bound(comp.begin(), comp.end(), x) - comp.begin() + 1; } inline void add(int i) { if(!used[i]) t.update(1, 1, comp.size(), gt(a[i]), 1); used[i] = true; } inline void del(int i) { if(used[i]) t.update(1, 1, comp.size(), gt(a[i]), -1); used[i] = false; } inline void del(int l, int r) { for(int i = l; i <= r; ++i) del(i); } inline void add(int l, int r) { for(int i = l; i <= r; ++i) add(i); } void calc_f(int start, int l, int r, int opt_l, int opt_r, int coef) { int mid = l + r >> 1; f[mid] = {-1, -inf}; for(int i = opt_l; i <= opt_r; ++i) { add(i); Max(f[mid], mp(t.get_sum_of_k(1, 1, comp.size(), mid - coef * (i - start)), -i)); } f[mid].se *= -1; assert(f[mid].f != -1); del(opt_l, opt_r); if(l < mid) calc_f(start, l, mid - 1, opt_l, f[mid].se, coef); add(opt_l, f[mid].se); if(mid < r) calc_f(start, mid + 1, r, f[mid].se, opt_r, coef); add(f[mid].se, opt_r); } void calc_g(int start, int l, int r, int opt_l, int opt_r, int coef = 1) { int mid = l + r >> 1; g[mid] = {-1, -inf}; for(int i = opt_r; i >= opt_l; --i) { add(i); Max(g[mid], mp(t.get_sum_of_k(1, 1, comp.size(), mid - coef * (start - 1 - i)), i)); } assert(g[mid].f != -1); del(opt_l, opt_r); if(l < mid) calc_g(start, l, mid - 1, g[mid].se, opt_r, coef); add(g[mid].se, opt_r); if(mid < r) calc_g(start, mid + 1, r, opt_l, g[mid].se, coef); add(opt_l, g[mid].se); } long long findMaxAttraction(int n, int start, int d, int attraction[]) { for(int i = 0; i < n; ++i) a[i+1] = attraction[i]; ++start; for(int i = 1; i <= n; ++i) comp.pb(a[i]); sort(comp.begin(), comp.end()); comp.erase(unique(comp.begin(), comp.end()), comp.end()); ll ans = 0; for(int i = start; i <= n; ++i) { add(i); Max(ans, t.get_sum_of_k(1, 1, comp.size(), d - (i - start))); } del(start, n); for(int i = start; i >= 1; --i) { add(i); Max(ans, t.get_sum_of_k(1, 1, comp.size(), d - (start - i))); } del(1, start); if(start == 1 || start == n) return ans; calc_f(start, 0, d, start, n, 2); del(start, n); calc_g(start, 0, d, 1, start - 1, 1); del(1, start - 1); // for(int i = 0; i <= d; ++i) // cout << i << ' ' << g[i].f << ' ' << g[i].se << endl; // return -1; for(int x = 0; x <= d; ++x) { int i = f[x].se; int lef = d - x - 1; if(lef >= 0) Max(ans, g[lef].f + f[x].f); } calc_f(start, 0, d, start, n, 1); del(start, n); calc_g(start, 0, d, 1, start - 1, 2); for(int x = 0; x <= d; ++x) { int i = g[x].se; int lef = d - x - 2; if(lef >= 0) Max(ans, f[lef].f + g[x].f); } return ans; }

Compilation message (stderr)

holiday.cpp: In member function 'void segment_tree::update(int, int, int, int, int)':
holiday.cpp:81:26: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
             int mid = tl + tr >> 1;
                       ~~~^~~~
holiday.cpp: In member function 'long long int segment_tree::get_sum_of_k(int, int, int, int)':
holiday.cpp:99:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
         int mid = tl + tr >> 1;
                   ~~~^~~~
holiday.cpp: In function 'void calc_f(int, int, int, int, int, int)':
holiday.cpp:134:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
     int mid = l + r >> 1;
               ~~^~~
holiday.cpp: In function 'void calc_g(int, int, int, int, int, int)':
holiday.cpp:156:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
     int mid = l + r >> 1;
               ~~^~~
holiday.cpp: In function 'long long int findMaxAttraction(int, int, int, int*)':
holiday.cpp:213:13: warning: unused variable 'i' [-Wunused-variable]
         int i = f[x].se;
             ^
holiday.cpp:225:13: warning: unused variable 'i' [-Wunused-variable]
         int i = g[x].se;
             ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...