题目大意
给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。
思路
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAX_INDEX = 100010, MAX_MAXVAL = MAX_INDEX, MAX_DEL_CNT = 50010, MAX_NODE = 9e6; int Queries[MAX_DEL_CNT]; long long Ans[MAX_DEL_CNT]; int TotIndex, TotDelCnt, MaxVal; struct Data { int Index, Val, AddTime; bool operator < (const Data& a) const { return AddTime < a.AddTime; } }_datas[MAX_INDEX]; struct Node { int lSonId, rSonId; int Cnt; Node() :lSonId(0), rSonId(0), Cnt(0) {} }_nodes[MAX_NODE]; int _vCount; struct RangeTree { private: int RootId; Node *NewNode() { return _nodes + ++_vCount; } void Update(int &curId, int l, int r, int p, int delta) { Node *cur = _nodes + curId; if (!curId) { cur = NewNode(); curId = cur - _nodes; } cur->Cnt += delta; if (l == r) return; int mid = (l + r) / 2; if (p <= mid) Update(cur->lSonId, l, mid, p, delta); if (p > mid) Update(cur->rSonId, mid + 1, r, p, delta); } long long QueryPrefix(int k) { Node *cur = RootId ? _nodes + RootId : NULL; int l = 1, r = MaxVal; long long ans = 0; while (l < r && cur) { int mid = (l + r) / 2; if (k >= mid) { ans += cur->lSonId ?_nodes[cur->lSonId].Cnt :0; cur = cur->rSonId ? _nodes + cur->rSonId : NULL; l = mid + 1; } else { cur = cur->lSonId ? _nodes + cur->lSonId:NULL; r = mid; } } return ans; } long long QuerySuffix(int k) { Node *cur = RootId ? _nodes + RootId : NULL; if (!cur) return 0; return cur->Cnt - QueryPrefix(k-1); } public: RangeTree() :RootId(0) {} void Update(int p, int delta) { if (p < 1 || p > MaxVal) return; Update(RootId, 1, MaxVal, p, delta); } long long Query(int l, int r) { if (l > r) return 0; long long ans1 = 0; if (l == 1) { ans1 = QueryPrefix(r); return ans1; } else if (r == MaxVal) { ans1= QuerySuffix(l); return ans1; } else return 0; } }; struct BinaryTree { private: RangeTree C[MAX_MAXVAL]; int N; int Lowbit(int x) { return x & -x; } public: BinaryTree(int n) :N(n) {} void Update(int p, int delta) { if (p < 0) return; while (p <= N) { C[p].Update(delta, 1); p += Lowbit(p); } } long long Query(int p, long long(*getVal)(RangeTree&, int), int cKey) { long long ans = 0; while (p > 0) { ans += getVal(C[p], cKey); p -= Lowbit(p); } return ans; } }*a; long long Range_GetIdGreaterCnt(RangeTree& tree, int k) { return tree.Query(k + 1, MaxVal); } long long Range_GetIdLesserCnt(RangeTree& tree, int k) { return tree.Query(1, k - 1); } void Update(Data& data) { a->Update(data.Val, data.Index); } long long Query(Data& data) { return a->Query(data.Val - 1, Range_GetIdGreaterCnt, data.Index) + a->Query(MaxVal, Range_GetIdLesserCnt, data.Index) - a->Query(data.Val, Range_GetIdLesserCnt, data.Index); } int main() { scanf("%d%d", &TotIndex, &TotDelCnt); MaxVal = TotIndex; static int Match[MAX_INDEX]; for (int i = 1; i <= TotIndex; i++) { _datas[i].Index = i; scanf("%d", &_datas[i].Val); Match[_datas[i].Val] = i; } int addTime = TotDelCnt; for (int i = 1; i <= TotDelCnt; i++) { int delId; scanf("%d", &delId); _datas[Match[delId]].AddTime = addTime--; } sort(_datas + 1, _datas + TotIndex + 1); a = new BinaryTree(MaxVal); long long tempAns = 0; for (int i = 1; i <= TotIndex - TotDelCnt; i++) { Update(_datas[i]); tempAns += Query(_datas[i]); } for (int i = TotIndex - TotDelCnt + 1; i <= TotIndex; i++) { Update(_datas[i]); Ans[_datas[i].AddTime] = tempAns += Query(_datas[i]); } for (int i = TotDelCnt; i >= 1; i--) printf("%lld ", Ans[i]); return 0; }