Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define SPEED ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
- #define fileio freopen("in.in", "r", stdin),freopen("out.out", "w", stdout);
- #define ll long long
- #define fi first
- #define se second
- #define mp make_pair
- #define pb push_back
- #define eb emplace_back
- #define pii pair<ll , ll>
- #define pll pair<long long ,long long >
- #define sd(x) scanf("%d",&x)
- #define sld(x) scanf("%lld",&x)
- #define pd(x) prllf("%d\n",x)
- #define pld(x) prllf("%lld\n",x)
- #define pss prllf
- #define mod 1000000007
- #define INF 1e18
- #define eps 0.00001
- #define debug(n1) cout<<n1<<endl
- const ll N = 3e5 + 5;
- const ll M = 320;
- ll n;
- ll m;
- pll a[N];
- pll tree1[4 * N];
- pll tree2[4 * N];
- ll ind1[4 * N];
- ll ind2[4 * N];
- set < ll > store[4 * N];
- void build_max(pll tree[] , ll A[] , ll node , ll s , ll e) {
- if(s == e) {
- tree[node].fi = A[s];
- tree[node].se = s;
- ind2[s] = node;
- return ;
- }
- ll mid = (s + e) / 2;
- build_max(tree , A , 2 * node + 1 , s , mid);
- build_max(tree , A , 2 * node + 2 , mid + 1 , e);
- if(tree[2 * node + 1].fi > tree[2 * node + 2].fi) {
- tree[node].fi = tree[2 * node + 1].fi;
- tree[node].se = tree[2 * node + 1].se;
- }
- else{
- tree[node].fi = tree[2 * node + 2].fi;
- tree[node].se = tree[2 * node + 2].se;
- }
- return ;
- }
- pll query_max(pll tree[] , ll node , ll s , ll e , ll l , ll r) {
- if(l > e || r < s) {
- return make_pair(LLONG_MIN , -1);
- }
- if(l <= s && r >= e) {
- return tree[node];
- }
- ll mid = (s + e) / 2;
- pll li = query_max(tree , 2 * node + 1 , s , mid , l , r);
- pll re = query_max(tree , 2 * node + 2 , mid + 1 , e , l , r);
- if(li.fi > re.fi) {
- return li;
- }
- else{
- return re;
- }
- }
- void build_min(pll tree[] , ll A[] , ll node , ll s , ll e) {
- if(s == e) {
- tree[node].fi = A[s];
- tree[node].se = s;
- ind1[s] = node;
- return ;
- }
- ll mid = (s + e) / 2;
- build_min(tree , A , 2 * node + 1 , s , mid);
- build_min(tree , A , 2 * node + 2 , mid + 1 , e);
- if(tree[2 * node + 1].fi < tree[2 * node + 2].fi) {
- tree[node].fi = tree[2 * node + 1].fi;
- tree[node].se = tree[2 * node + 1].se;
- }
- else{
- tree[node].fi = tree[2 * node + 2].fi;
- tree[node].se = tree[2 * node + 2].se;
- }
- return ;
- }
- pll query_min(pll tree[] , ll node , ll s , ll e , ll l , ll r) {
- if(l > e || r < s) {
- return make_pair(LLONG_MAX , -1);
- }
- if(l <= s && r >= e) {
- return tree[node];
- }
- ll mid = (s + e) / 2;
- pll li = query_min(tree , 2 * node + 1 , s , mid , l , r);
- pll re = query_min(tree , 2 * node + 2 , mid + 1 , e , l , r);
- if(li.fi < re.fi) {
- return li;
- }
- else{
- return re;
- }
- }
- void update_max(pll tree[] , ll node, ll b, ll e, ll idx, ll val)
- {
- if (b>e || b>idx || e<idx ) return;
- if (node == ind2[idx]) //at leaf node
- {
- tree[node].fi = val;
- tree[node].se = -1;
- return;
- }
- update_max( tree , node*2 + 1 , b , (b+e)/2 , idx, val );
- update_max( tree , node*2 + 2 , (b+e)/2 + 1 , e , idx, val );
- if(tree[2 * node + 1].fi > tree[2 * node + 2].fi) {
- tree[node].fi = tree[2 * node + 1].fi;
- tree[node].se = tree[2 * node + 1].se;
- }
- else{
- tree[node].fi = tree[2 * node + 2].fi;
- tree[node].se = tree[2 * node + 2].se;
- }
- return ;
- }
- void update_min(pll tree[] , ll node, ll b, ll e, ll idx, ll val)
- {
- if (b>e || b>idx || e<idx ) return;
- if (node == ind1[idx])
- {
- tree[node].fi = val;
- tree[node].se = -1;
- return;
- }
- update_min( tree , node*2 + 1 , b , (b+e)/2 , idx, val );
- update_min( tree , node*2 + 2 , (b+e)/2 + 1 , e , idx, val );
- //now some change might have been made in either of the child nodes.
- if(tree[2 * node + 1].fi < tree[2 * node + 2].fi) {
- tree[node].fi = tree[2 * node + 1].fi;
- tree[node].se = tree[2 * node + 1].se;
- }
- else{
- tree[node].fi = tree[2 * node + 2].fi;
- tree[node].se = tree[2 * node + 2].se;
- }
- return ;
- }
- ll ai[N];
- int main() {
- sld(n);
- for(ll i = 1 ; i <= n ; i++) {
- sld(a[i].fi);
- a[i].se = i;
- ai[i] = a[i].fi;
- store[a[i].fi].insert(i);
- }
- build_min(tree1 , ai , 1 , 1 , n);
- build_max(tree2 , ai , 1 , 1 , n);
- sort(a + 1 , a + n + 1);
- ll res = 0;
- for(ll i = 1 ; i <= n ; i++) {
- pll ans1 = a[i];
- pll ans2 = query_max(tree2 , 1 , 1 , n , ans1.se + 1LL , n);
- if(ans2.fi > 4 * N) continue;
- if(store[ans2.fi].size() > 0)
- {
- if(store[ans2.fi].upper_bound(ans1.se) != store[ans2.fi].end())
- ans2.se = (*store[ans2.fi].upper_bound(ans1.se));
- }
- // cout << ans1.fi << " " << ans2.fi << endl;
- if(ans1.fi < ans2.fi && ans1.se < ans2.se) {
- res += ans2.fi - ans1.fi;
- // cout << ans1.se << " ff " << ans2.se << endl;
- update_min(tree1 , 1 , 1 , n , ans1.se , LLONG_MAX);
- update_max(tree2 , 1 , 1 , n , ans2.se , LLONG_MIN);
- store[ans2.fi].erase(ans2.se);
- }
- }
- cout << res << endl;
- return 0;
- }
Add Comment
Please, Sign In to add comment