Submission #696906

#TimeUsernameProblemLanguageResultExecution timeMemory
696906CDuongIzbori (COCI22_izbori)C++17
0 / 110
115 ms60764 KiB
/* #pragma GCC optimize("Ofast,unroll-loops") #pragma GCC target("avx2,fma,bmi,bmi2,sse4.2,popcnt,lzcnt") */ #include <bits/stdc++.h> #define taskname "" #define all(x) x.begin(), x.end() #define int long long #define ll long long #define ld long double #define pb push_back #define ff first #define ss second #define pii pair<int, int> #define pll pair<ll, ll> #define vi vector<int> using namespace std; const int mxN = 2e5 + 5; const int mod = 1e9 + 7; const ll oo = 1e18; struct node { ll val, val1, lazy; node() {val = val1 = lazy = 0;} } segtree[10 * mxN]; struct op { int st, en, val; }; ll ans; int n, a[mxN], cnt; map<int, int> mp; vi num, appearance[mxN]; ll calc(ll l, ll r) { ll len = r - l + 1; return ((l + r) * len / 2); } void down(ll idx, ll l, ll r) { if(segtree[idx].lazy == 0) return; ll tmp = segtree[idx].lazy, mid = (l + r) >> 1; segtree[idx << 1].val += (mid - l + 1) * tmp; segtree[idx << 1].val1 += calc(1, mid - l + 1) * tmp; segtree[idx << 1].lazy += tmp; segtree[idx << 1 | 1].val += (r - mid) * tmp; segtree[idx << 1 | 1].val1 += calc(1, r - mid) * tmp; segtree[idx << 1 | 1].lazy += tmp; segtree[idx].lazy = 0; } void merge(node &res, node &a, node &b, ll len) { res.val = a.val + b.val; res.val1 = a.val1 + a.val * len + b.val1; } void update(int l, int r, int idx, int u, int v, int val) { if(v < l || r < u) return; if(u <= l && r <= v) { segtree[idx].val += (ll)(val) * (ll)(r - l + 1); segtree[idx].val1 += (ll)(val) * calc(1, r - l + 1); segtree[idx].lazy += val; return; } down(idx, l, r); int mid = (l + r) >> 1; update(l, mid, idx << 1, u, v, val); update(mid + 1, r, idx << 1 | 1, u, v, val); merge(segtree[idx], segtree[idx << 1], segtree[idx << 1 | 1], r - mid); } ll get_normal(int l, int r, int idx, int u, int v) { if(v < l || r < u) return 0; if(u <= l && r <= v) return segtree[idx].val; down(idx, l, r); int mid = (l + r) >> 1; return (get_normal(l, mid, idx << 1, u, v) + get_normal(mid + 1, r, idx << 1 | 1, u, v)); } pll get(int l, int r, int idx, int u, int v) { // cout << l << " " << r << " " << idx << " " << u << " " << v << endl; // if(v < l || r < u) // return {0, 0}; if(u <= l && r <= v) return {segtree[idx].val1, segtree[idx].val}; down(idx, l, r); int mid = (l + r) >> 1; if(mid < u) return get(mid + 1, r, idx << 1 | 1, u, v); if(v < mid + 1) return get(l, mid, idx << 1, u, v); else { pll tmp = get(l, mid, idx << 1, u, v); pll tmp1 = get(mid + 1, r, idx << 1 | 1, u, v); ll len = v - mid; ll sum = tmp1.ff + tmp.ff + tmp.ss * len; ll sum1 = tmp.ss + tmp1.ss; return {sum, sum1}; } } ll get_sum(int l, int r) { // cout << "boom: " << l << " " << r << endl; if(l == r) return get_normal(1, 2 * n + 20, 1, 1, l - 1); pll res = get(1, 2 * n + 20, 1, l, r - 1); // cout << endl << "l = " << l << ", r - 1 = " << r - 1 << ", res = " << res.ff << endl; if(l == 1) return res.ff; res.ff += get_normal(1, 2 * n + 20, 1, 1, l - 1) * (ll)(r - l + 1); return res.ff; } void solve() { cin >> n; for(int i = 1; i <= n; ++i) { cin >> a[i]; num.pb(a[i]); } sort(all(num)); num.erase(unique(all(num)), num.end()); for(int val : num) mp[val] = ++cnt; for(int i = 1; i <= n; ++i) { a[i] = mp[a[i]]; appearance[a[i]].pb(i); } for(int i = 1; i <= (int)num.size(); ++i) { vector<op> ops; int sz = appearance[i].size(); appearance[i].pb(n + 1); update(1, 2 * n + 20, 1, n - appearance[i][0] + 7, n + 6, 1); ops.pb({n - appearance[i][0] + 7, n + 6, -1}); // cout << 0 << " " << n - appearance[i][0] - n + 1 << endl; int cur_sum = n - appearance[i][0] + 8; ll daubuoi = 0; for(int j = 0; j < sz; ++j) { int cur = appearance[i][j], nxt = appearance[i][j + 1]; int len = nxt - cur, nxt_sum = cur_sum - len + 1; // cout << cur << ": "; // cout << cur_sum - n - 1 << " " << nxt_sum - n - 1 << " = "; ll tmp = get_sum(nxt_sum, cur_sum); // cout << tmp << endl; ans += tmp; daubuoi += tmp; // cout << tmp << endl; update(1, 2 * n + 20, 1, nxt_sum, cur_sum, 1); ops.pb({nxt_sum, cur_sum, -1}); cur_sum = nxt_sum + 1; } for(auto [st, en, val] : ops) update(1, 2 * n + 20, 1, st, en, val); // cout << daubuoi << endl; } cout << ans << endl; } signed main() { #ifndef CDuongg if(fopen(taskname".inp", "r")) assert(freopen(taskname".inp", "r", stdin)), assert(freopen(taskname".out", "w", stdout)); #else freopen("bai3.inp", "r", stdin); freopen("bai3.out", "w", stdout); auto start = chrono::high_resolution_clock::now(); #endif ios_base::sync_with_stdio(false); cin.tie(nullptr); int t = 1; //cin >> t; while(t--) solve(); #ifdef CDuongg auto end = chrono::high_resolution_clock::now(); // cout << "\n"; for(int i = 1; i <= 100; ++i) cout << '='; // cout << "\nExecution time: " << chrono::duration_cast<chrono::milliseconds> (end - start).count() << "[ms]" << endl; #endif }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...