[CQOI2011]动态逆序对

Description

对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。

Input

输入第一行包含两个整数nm,即初始元素的个数和删除的元素个数。以下n行每行包含一个1到n之间的正整数,即初始排列。以下m行每行一个正整数,依次为每次删除的元素。
 

Output

 
输出包含m行,依次为删除每个元素之前,逆序对的个数。

Sample Input

5 4
1
5
3
4
2
5
1
4
2

Sample Output

5
2
2
1

样例解释
(1,5,3,4,2)(1,3,4,2)(3,4,2)(3,2)(3)。

HINT

N<=100000 M<=50000

树状数组+主席树

每一次删除x,我们求出前面大于x和后面小于x的个数减去

这个用按位置作为前缀加入元素的主席树

但有一个问题就是,作为前缀的一个元素x被删,后面的x+1~n就都要修改更新

这样就会退化成O(n^2logn)

所以用树状数组维护主席树

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define lowbit(x) ((x)&(-(x)))
 7 using namespace std;
 8 typedef long long lol;
 9 int pos,root[100001],ch[90*100001][2],n,m,a[100001],p[100001];
10 lol ans;
11 int sum[90*100001];
12 void update(int &rt,int l,int r,int x,int d)
13 {
14   if (!rt)
15       rt=++pos;
16   sum[rt]+=d;
17   if (l==r) return;
18   int mid=(l+r)>>1;
19   if (x<=mid) update(ch[rt][0],l,mid,x,d);
20   else update(ch[rt][1],mid+1,r,x,d);
21 }
22 lol query1(int rt,int l,int r,int x)
23 {
24   if (l==r) return sum[rt];
25   int mid=(l+r)>>1;
26   if (x<=mid) return query1(ch[rt][0],l,mid,x)+sum[ch[rt][1]];
27   else return query1(ch[rt][1],mid+1,r,x);
28 }
29 lol query2(int rt,int l,int r,int x)
30 {
31   if (l==r)
32     return sum[rt];
33   int mid=(l+r)>>1;
34   if (x<=mid) return query2(ch[rt][0],l,mid,x);
35   else return query2(ch[rt][1],mid+1,r,x)+sum[ch[rt][0]];
36 }
37 int main()
38 {int i,j,x,k;
39   cin>>n>>m;
40   for (i=1;i<=n;++i)
41     {
42       scanf("%d",&a[i]);
43       p[a[i]]=i;
44       for (j=i;j<=n;j+=lowbit(j))
45     update(root[j],1,n,a[i],1);
46     }
47   for (i=1;i<=n;++i)
48     {
49       for (j=i-1;j;j-=lowbit(j))
50     ans+=query1(root[j],1,n,a[i]);
51     }
52   for (i=1;i<=m;++i)
53     {
54       scanf("%d",&x);
55       printf("%lld\n",ans);
56       k=p[x];
57       for (j=k-1;j;j-=lowbit(j))
58     ans-=query1(root[j],1,n,x);
59       for (j=k;j;j-=lowbit(j))
60     ans+=query2(root[j],1,n,x);
61       for (j=n;j;j-=lowbit(j))
62     ans-=query2(root[j],1,n,x);
63       for (j=k;j<=n;j+=lowbit(j))
64     update(root[j],1,n,x,-1);
65     }
66 }

 

posted @ 2018-01-09 10:15  Z-Y-Y-S  阅读(219)  评论(0编辑  收藏  举报