BZOJ 3192: [JLOI2013]刪除物品 奇淫技巧&樹狀數組
阿新 • • 發佈:2017-10-28
lap 一次 arr 移動 bzoj3 tree 樹狀數組 blank opened
點我看題
這題十分奇淫技巧...QAQ因為知道是樹狀數組的題QAQ剛開始以為維護兩個數組的樹狀數組然後模擬從大到小,然後發現不會打QAQ
於是悄悄咪咪翻開題解了。
實際上兩個數組可以看做一個數組
如 1 4 5
2 7 3
實際上就是 5 4 1 | 2 7 3
“|”這個地方就是假設成一個指標,然後每次把這個指標移到某一個位置,這個位置左右兩個邊的數就可以刪除。
所以就模擬從大到小刪數。
第一次 5 4 1 2 | 7 3
指標移動1次就可以刪掉“7”
第二次 5 | 4 1 2 3
指標移動3次就可以刪掉“5”
第三次 |4 1 2 3
指標不需要移動就可以刪除“4”
......
然後就把這些移動的次數加起來就是答案~\(≧▽≦)/~啦啦啦
把刪掉的數的位置 置0 有數的位置 置1 然後樹狀數組維護一下就好了~
1 var a,c,tree:array[0..200500]of int64; 2 i,n,m,p:longint; 3 x,ans:int64; 4 5 procedure qs(l,r:longint); 6 var i,j:longint; 7 m,t:int64; 8 begin 9 i:=l; 10 j:=r; 11 m:=a[(l+r)>>1];BZOJ319212 repeat 13 while a[i]>m do inc(i); 14 while a[j]<m do dec(j); 15 if i<=j then 16 begin 17 t:=a[i];a[i]:=a[j];a[j]:=t; 18 t:=c[i];c[i]:=c[j];c[j]:=t; 19 inc(i); 20 dec(j); 21 end; 22 until i>j; 23 if l<j then qs(l,j); 24 if i<r thenqs(i,r); 25 end; 26 function low(x:longint):longint; 27 begin 28 exit(x and -x); 29 end; 30 procedure adde(x,d:longint); 31 begin 32 while x<=p do 33 begin 34 inc(tree[x],d); 35 inc(x,low(x)); 36 end; 37 end; 38 function sum(x:longint):int64; 39 var s:int64; 40 begin 41 s:=0; 42 while x>0 do 43 begin 44 inc(s,tree[x]); 45 dec(x,low(x)); 46 end; 47 exit(s); 48 end; 49 begin 50 read(n,m); 51 p:=n+m; 52 for i:=n downto 1 do 53 begin 54 read(a[i]); 55 c[i]:=i; 56 adde(i,1); 57 end; 58 for i:=n+1 to p do 59 begin 60 read(a[i]); 61 c[i]:=i; 62 adde(i,1); 63 end; 64 qs(1,p); 65 if c[1]>n then x:=n+1 else x:=n; 66 ans:=0; 67 for i:=1 to p do 68 begin 69 adde(c[i],-1); 70 if c[i]>x then ans:=ans+sum(c[i])-sum(x-1) else 71 ans:=ans+sum(x)-sum(c[i]-1); 72 x:=c[i]; 73 end; 74 writeln(ans); 75 end.
BZOJ 3192: [JLOI2013]刪除物品 奇淫技巧&樹狀數組