[CQOI2011]动态逆序对
Description
对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。
Input
输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数。以下n行每行包含一个1到n之间的正整数,即初始排列。以下m行每行一个正整数,依次为每次删除的元素。
Output
输出包含m行,依次为删除每个元素之前,逆序对的个数。
Sample Input
5 4
1
5
3
4
2
5
1
4
2
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)。
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 }