题意:对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。
给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。
N<=100000 M<=50000
思路:树套树即可,第i棵树维护前i位中1-j的个数,支持区间求和
外面要套BIT来实现区间加
本来维护剩下的数就可以,但初始化可能要开(n log^2 n) 个个节点,这题又只有128MB……
所以只能维护删除的数了,如果256MB乱搞就行了……
1 var t:array[0..5100000,0..1]of longint; 2 sum:array[0..5100000]of int64; 3 root,a,b,a1,a2,c:array[0..110000]of longint; 4 n,m,i,x,cnt,l,r,j:longint; 5 ans:int64; 6 7 8 procedure pushup(x:longint); 9 begin 10 l:=t[x,0]; r:=t[x,1]; 11 sum[x]:=sum[l]+sum[r]; 12 end; 13 14 procedure update(l,r,x,v:longint;var p:longint); 15 var mid:longint; 16 begin 17 if p=0 then 18 begin 19 inc(cnt); p:=cnt; 20 end; 21 if l=r then 22 begin 23 sum[p]:=sum[p]+v; exit; 24 end; 25 mid:=(l+r)>>1; 26 if x<=mid then update(l,mid,x,v,t[p,0]); 27 if x>mid then update(mid+1,r,x,v,t[p,1]); 28 pushup(p); 29 end; 30 31 function query(l,r,x,y,p:longint):int64; 32 var mid:longint; 33 begin 34 if p=0 then exit(0); 35 if (l>=x)and(r<=y) then exit(sum[p]); 36 mid:=(l+r)>>1; 37 query:=0; 38 if x<=mid then query:=query+query(l,mid,x,y,t[p,0]); 39 if y>mid then query:=query+query(mid+1,r,x,y,t[p,1]); 40 pushup(p); 41 end; 42 43 function lowbit(x:longint):longint; 44 begin 45 exit(x and (-x)); 46 end; 47 48 procedure change(i,j,v:longint); 49 var k:longint; 50 begin 51 k:=i; 52 while k<=n do 53 begin 54 update(1,n,j,v,root[k]); 55 k:=k+lowbit(k); 56 end; 57 end; 58 59 function getsum(x:longint):longint; 60 begin 61 getsum:=0; 62 while x>0 do 63 begin 64 getsum:=getsum+c[x]; 65 x:=x-lowbit(x); 66 end; 67 end; 68 69 function ask(i,j,x,y:longint):int64; 70 var k:longint; 71 begin 72 ask:=0; 73 if i>j then exit(0); 74 if x>y then exit(0); 75 k:=j; 76 while k>0 do 77 begin 78 ask:=ask+query(1,n,x,y,root[k]); 79 k:=k-lowbit(k); 80 end; 81 k:=i-1; 82 while k>0 do 83 begin 84 ask:=ask-query(1,n,x,y,root[k]); 85 k:=k-lowbit(k); 86 end; 87 end; 88 89 begin 90 assign(input,'bzoj3295.in'); reset(input); 91 assign(output,'bzoj3295.out'); rewrite(output); 92 readln(n,m); 93 94 for i:=1 to n do 95 begin 96 read(a[i]); 97 b[a[i]]:=i; 98 a1[i]:=getsum(n)-getsum(a[i]); 99 ans:=ans+a1[i]; 100 j:=a[i]; 101 while j<=n do 102 begin 103 inc(c[j]); 104 j:=j+lowbit(j); 105 end; 106 end; 107 108 fillchar(c,sizeof(c),0); 109 for i:=n downto 1 do 110 begin 111 a2[i]:=getsum(a[i]-1); 112 j:=a[i]; 113 while j<=n do 114 begin 115 inc(c[j]); 116 j:=j+lowbit(j); 117 end; 118 end; 119 120 { for i:=1 to n do write(a1[i],' '); 121 writeln; 122 for i:=1 to n do write(a2[i],' '); } 123 for i:=1 to m do 124 begin 125 readln(x); 126 writeln(ans); 127 j:=b[x]; 128 ans:=ans-(a1[j]+a2[j]-ask(1,j-1,x+1,n)-ask(j+1,n,1,x-1)); 129 change(j,x,1); 130 end; 131 132 133 close(input); 134 close(output); 135 end.