题目大意
给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;
}