1. 程式人生 > >CodeForces540E【樹狀陣列+二分】

CodeForces540E【樹狀陣列+二分】

思路:
1:變換的做一次樹狀陣列求逆序就好了
2:然後就是對於變換的求前面有多少個比他大,後面有多少個比他小
具體:
對於當前位置,前面有多少比他大,然後減去被佔多少位置(二分就好)
對於後面位置,後面有多少比他小,然後減去被佔多少位置(二分就好)
然後就是模擬了。。然後就過了~

#include <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
#define lson num<<1,Left,Mid
#define rson num<<1|1, Mid+1, Right
typedef long long LL; const int Maxn = 2e5 + 10; LL c[Maxn]; inline int lowbit(int x){return x & -x;} LL Sum(int x){ LL ans = 0; while(x){ ans = ans + c[x]; x = x - lowbit(x); } return ans; } void add(int x){ while(x < Maxn){ ++c[x]; x = x + lowbit(x); } } vector
<int>
xs, p; int getid(int x){return lower_bound(xs.begin(), xs.end(), x) - xs.begin() + 1;} struct asd{ int id, w; }node[Maxn]; bool cmp(asd x, asd y){ return x.id > y.id; } map<int, int>mp; int n; int p1, p2, w1, w2; void solve(){ if(mp.find(p1) == mp.end()) w1 = p1; else
w1 = mp[p1]; if(mp.find(p2) == mp.end()) w2 = p2; else w2 = mp[p2]; mp[p1] = w2; mp[p2] = w1; } int main(){ scanf("%d", &n); for(int i=1;i<=n;i++){ scanf("%d%d",&p1,&p2); solve(); xs.push_back(mp[p1]); xs.push_back(mp[p2]); p.push_back(p1); p.push_back(p2); } sort(p.begin(), p.end()), p.erase(unique(p.begin(), p.end()), p.end()); sort(xs.begin(), xs.end()), xs.erase(unique(xs.begin(), xs.end()), xs.end()); int num = 0; int sz = p.size(); for(int i=0;i<sz;++i){ node[num].id = p[i]; node[num++].w = mp[p[i]]; } sort(node, node+num, cmp); LL ans = 0; for(int i=0;i<num;i++){ add(getid(node[i].w)); ans = ans + Sum(getid(node[i].w) - 1); } // printf("%d\n" , ans); int p1, p2, it1, it2, Left, Right; LL pos, w, len, ext; for(int i=0;i<num;i++){ pos = node[i].id; w = node[i].w; if(pos > w){ len = pos - w - 1; p1 = w + 1; p2 = pos - 1; Left = 0, Right = p.size()-1; while(Left < Right){ int Mid = Left + (Right - Left) / 2; if(p[Mid] >= p1) Right = Mid; else Left = Mid + 1; } it1 = Left; Left = 0, Right = p.size()-1; while(Left < Right){ int Mid = Left + (Right - Left) / 2; if(p[Mid] > p2) Right = Mid; else Left = Mid + 1; } it2 = Left; if(p[it1] >= p1 && p[it2] > p2){ ext = it2 - it1; // printf("%I64d\n", ext); ans = ans + len - ext; } } if(w > pos){ len = w - pos - 1; p1 = pos + 1; p2 = w - 1; Left = 0, Right = p.size()-1; while(Left < Right){ int Mid = Left + (Right - Left) / 2; if(p[Mid] >= p1) Right = Mid; else Left = Mid + 1; } it1 = Left; Left = 0, Right = p.size()-1; while(Left < Right){ int Mid = Left + (Right - Left) / 2; if(p[Mid] > p2) Right = Mid; else Left = Mid + 1; } it2 = Left; if(p[it1] >= p1 && p[it2] > p2){ ext = it2 - it1; // printf("%I64d\n", ext); ans = ans + len - ext; } } } printf("%I64d\n", ans); }