1. 程式人生 > >BZOJ 3192: [JLOI2013]刪除物品 奇淫技巧&樹狀數組

BZOJ 3192: [JLOI2013]刪除物品 奇淫技巧&樹狀數組

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];
12 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 then
qs(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.
BZOJ3192

BZOJ 3192: [JLOI2013]刪除物品 奇淫技巧&樹狀數組