排序 紀中 1386 樹狀陣列 玄學

2021-07-14 20:16:29 字數 1609 閱讀 3433

你收到一項對陣列進行排序的任務,陣列中是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...