P1347 - [CQOI2011]动态逆序对

P1347 - [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

Sample Output

5
2
2
1

Hint

样例解释
(1,5,3,4,2)(1,3,4,2)(3,4,2)(3,2)(3)。
数据规模:
N<=100000 , M<=50000

Source

耒阳大视野,CQOI
主席树, 分治 ,可持久化, 分块 ,陈丹琦分治

 

思路{

  此题是三维偏序的一道应用题;

  多存一个时间戳

  则问题转化为三维偏序{

      一维时间戳

      二维在数组中的位置

      三维为值

  第一维在输入预处理完

  第二维 CDQ分治 第三维树状数组

  或 第三维CDQ分治 第二维树状数组

  目的是为了不漏掉一些相应情况

  }

  从后开始,化删去为插入;

  求解即可

}

反思:该题真正体现了CDQ分治的离线分治的思想。需要多加体会!

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<queue>
 7 #include<ctime>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 #define MAXX 100001
12 #define LL long long
13 #define RG register
14 #define lowbit(k) k&-k
15 using namespace std;
16 LL n,m,tot,T,a[MAXX],pos[MAXX],v[MAXX],tree[MAXX],col[MAXX];
17 struct node{
18   int d,ps,id;
19 }q[MAXX];
20 LL ans[MAXX];
21 //                                   sort
22 bool Comp1(const node & x,const node & y){return x.d>y.d;}
23 bool Comp2(const node & x,const node & y){return x.ps>y.ps;}
24 //                                   shuzhuangshuzu
25 void add(LL k){
26   for(;k<=n;k+=lowbit(k)){
27     if(col[k]!=T)tree[k]=0;
28     col[k]=T,tree[k]++;
29   }
30 }
31 LL sum(LL k){
32   LL num=0;
33   for(;k;k-=lowbit(k))if(col[k]==T)num+=tree[k];
34   return num;
35 }
36 //                                  CDQfenzhi
37 void CDQ(int l,int r){
38   if(l==r) return;int mid=(l+r)>>1;
39   CDQ(l,mid);CDQ(mid+1,r);
40   sort(q+l,q+mid+1,Comp1);
41   sort(q+mid+1,q+r+1,Comp1);RG int i,j;T++;
42   for(j=l,i=mid+1;i<=r;i++){
43     for(;q[j].d>q[i].d&&j<=mid;j++)
44       add(q[j].ps);
45     ans[q[i].id]+=sum(q[i].ps);
46   }T++;
47   sort(q+l,q+mid+1,Comp2);
48   sort(q+mid+1,q+r+1,Comp2);
49   for(j=l,i=mid+1;i<=r;i++){
50     for(;q[j].ps>q[i].ps&&j<=mid;j++){
51       add(q[j].d);
52     }
53     ans[q[i].id]+=sum(q[i].d);
54   }
55 }
56 int main(){ 
57   scanf("%lld%lld",&n,&m);
58   for(RG int i=1;i<=n;i++){
59     int uu;
60     scanf("%d",&uu);
61         a[i]=uu;pos[uu]=i;
62   }
63   for(RG int i=1;i<=m;i++){
64     int uu;scanf("%d",&uu);
65     uu=pos[uu];v[uu]=1;
66     q[n-i+1].d=a[uu];
67     q[n-i+1].ps=uu;
68     q[n-i+1].id=n-i+1;
69   }
70   for(RG int i=1;i<=n;i++) if(!v[i]){
71       q[++tot].d=a[i];// quanzhi
72       q[tot].ps=i;// weizhi
73       q[tot].id=tot;//shijin
74     }
75   CDQ(1,n);// yi jing an shi jian pai wan xu
76   for(RG int i=1;i<=n;i++) ans[i]+=ans[i-1];
77   for(RG int i=n;i>n-m;i--) printf("%lld\n",ans[i]);
78    return 0;
79 }

 

posted @ 2017-03-31 14:42  QYP_2002  阅读(177)  评论(0编辑  收藏  举报