BZOJ3295 动态逆序对(树状数组套线段树)
[Cqoi2011]动态逆序对
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6058 Solved: 2117
[Submit][Status][Discuss]
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
Source
题解:
普通的树状数组,无法记录位置,不能知道一次之后记录的是所以位置的信息,
一次删除的时候,不能知道哪些值是比它小的,因为位置的影响,
所以需要树套树,在开一层位置,这样就可以了,动态开点,n logn log n的空间复杂度。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 7 #define N 100007 8 #define M 10000007 9 using namespace std; 10 int n,m,cnt; 11 int a[N],id[N],bit[N],lson[M],rson[M],tree[M]; 12 long long ans; 13 14 int lowbit(int x){return x&-x;} 15 void addy(int &u,int l,int r,int x,int y) 16 { 17 if(!u)u=++cnt; 18 if(l==r){tree[u]+=y;return;} 19 int mid=(l+r)>>1; 20 if(x<=mid) addy(lson[u],l,mid,x,y); 21 else addy(rson[u],mid+1,r,x,y); 22 tree[u]=tree[lson[u]]+tree[rson[u]]; 23 } 24 void addx(int x,int y,int val) 25 { 26 for (int i=x;i<=n;i+=lowbit(i)) 27 addy(i,1,n,y,val); 28 } 29 int queryy(int u,int l,int r,int i,int j) 30 { 31 if(!u) return 0; 32 if(l==i&&r==j) return tree[u]; 33 int mid=(l+r)>>1; 34 if(j<=mid) return queryy(lson[u],l,mid,i,j); 35 else if(i>mid) return queryy(rson[u],mid+1,r,i,j); 36 return queryy(lson[u],l,mid,i,mid)+queryy(rson[u],mid+1,r,mid+1,j); 37 } 38 int queryx(int x,int l,int r) 39 { 40 int ans=0; 41 for (int i=x;i>=1;i-=lowbit(i)) 42 ans+=queryy(i,1,n,l,r); 43 return ans; 44 } 45 int main() 46 { 47 scanf("%d%d",&n,&m),cnt=n; 48 for(int i=1;i<=n;i++) 49 { 50 scanf("%d",&a[i]); 51 ans+=(long long)queryx(i-1,a[i]+1,n); 52 id[a[i]]=i; 53 addx(i,a[i],1); 54 } 55 while(m--) 56 { 57 printf("%lld\n",ans); 58 int x;scanf("%d",&x); 59 ans-=(long long)queryx(id[x]-1,x+1,n); 60 ans-=(long long)queryx(n,1,x-1); 61 ans+=(long long)queryx(id[x]-1,1,x-1); 62 addx(id[x],x,-1); 63 } 64 }