你收到一項對陣列進行排序的任務,陣列中是1到n個乙個排列。你突然想出以下一種特別的排序方法,分為以下n個階段:
•階段1,把數字1通過每次交換相鄰兩個數移到位置1;
•階段2,用同樣的方法把n移到位置n;
•階段3,把數字2移到位置2處;
•階段4,把數字n-1移到位置n-1處;
•依此類推。
換句話說,如果當前階段為奇數,則把最小的未操作的數移到正確位置上,如果階段為偶數,則把最大的未操作的數移到正確位置上。
寫乙個程式,給出初始的排列情況,計算每一階段交換的次數。
第一行包含乙個整數n(1<=n<=100000),表示陣列中元素的個數。
接下來n行每行乙個整數描述初始的排列情況。
輸出每一階段的交換次數。
對於每乙個點用0和1標記是否排過序
因為每次交換只會置換未排序的項,於是問題就轉變成了求向前或向後有多少數字還未排序,也就是1的個數
樹狀陣列可以求區間和,線段樹也行
硬是沒想到正解,優美的暴力過70分。
載自olahiuj
var
b:array[1..100010] of longint;
a:array[1..100010] of longint;
i,j,k:longint;
l,r:longint;
n,m:longint;
procedure
bian
(p,c:longint);
begin
while p<=m do
begin
b[p]:=b[p]+c;
p:=p+(p and (p xor (p-1)));
end;
end;
function
tong
(p:longint):longint;
begin
tong:=0;
while p>0
dobegin
tong:=tong+b[p];
p:=p-(p and (p xor (p-1)));
end;
end;
begin
readln(n);
m:=n;
for i:=1
to n do
begin
readln(j);
a[j]:=i;
end;
for i:=1
to n do
bian(i,1);
l:=0; r:=n+1;
for i:=1
to n do
case i mod2of
1:begin
writeln(tong(a[(i+1) div
2])-1);
bian(a[(i+1) div
2],-1);
end;
0:begin
writeln(tong(n)-tong(a[n-(i-1) div
2]));
bian(a[n-(i-1) div
2],-1);
end;
end;
end.
樹狀陣列 真玄學
真tm玄學 int lowbit int o void add int p,int v inthe int k return ans 掛個vj鏈結 模板題,直接照板子寫 要是不在專題裡,我怎麼想的到用樹狀陣列啊,玄學啊 題目的巧妙之處在於先從左到右,在從下到上寫入星星。所以縱座標其實不會影響結果 f...
外星人入侵 紀中3077 spfa 玄學優化
外星人入侵地球。可怕的吃人外星人正在全國各地依次序建立它們的基地。全國共有n 1 n 10,000 座城市,城市編號1 n。城市之間有m 0 m 100,000 條雙向道路相連。外星人計畫建立a 0 a n 個基地。你只有在距離當前所有外星人基地至少k 1 k 100 單位長度的城市才能得到安全。所...
排序(離散化 樹狀陣列)
題目 資料範圍大,交換相鄰的的樹,使有序 解題說明 關鍵是知道,每個數交換的次數是其前面比它大的樹的個數。用樹狀陣列維護一下 ac include include include includeusing namespace std typedef long long ll const int ma...