樹狀陣列求Thair對數

2021-07-17 02:19:47 字數 2804 閱讀 3179

thair問題

【問題描述】

在含有n個數的序列a[1]..a[n]中,三個數被稱作"thair"當且僅當i

const maxn=100005;

var a,b,c,id,ref:array[0..maxn] of longint;//ref(reflection)陣列,即對映陣列,用來離散

f,g:array[0..maxn] of int64;//f[i]表示以i結尾,前面有幾個比a[i]小的元素;

//g[i]表示以i開頭,後面有幾個比a[i]大的元素;

n,m:longint; ans:int64;//n<=100000,由於我們要記錄sigma(i=1,n) f[i]*g[i]的值,最多會超出maxlongint的上限;

procedure init;

var i:longint;

begin

readln(n);

for i:=1 to n do

begin

read(a[i]);

id[i]:=i;

end;

b:=a;

end;

function lowbit(now:longint):longint;

begin

exit(now and (-now));

end;

procedure update(now:longint);

begin

while (now<=n) do

begin

inc(c[now]);

inc(now,lowbit(now));

end;

end;

function query(now:longint):longint;

var sum:longint;

begin

sum:=0;

while (now>0) do

begin

inc(sum,c[now]);

dec(now,lowbit(now));

end;

exit(sum);

end;

//以上是樹狀陣列的3個基本操作

procedure swap(var x,y:longint);

var t:longint;

begin

t:=x; x:=y; y:=t;

end;

procedure qsort_gosmall(l,r:longint);

var i,j,mid:longint;

begin

i:=l; j:=r; mid:=a[l+random(r-l+1)];

repeat

while a[i]>mid do inc(i);

while a[j]j;

if imid do dec(j);

if i<=j then

begin

swap(a[i],a[j]); swap(id[i],id[j]);

inc(i); dec(j);

end;

until i>j;

if ia[i-1] then

begin

inc(m);

ref[id[i]]:=m;

endelse ref[id[i]]:=m; //離散的思想,由於題目給出的條件兩書不能相等,

//所以要做「去重」工作,但並非真正的去重

fillchar(c,sizeof(c),0);

for i:=1 to n do

begin

update(ref[i]);

f[i]:=i-query(ref[i]);

end;

end;

procedure ca_behind;

var i:longint;

begin

for i:=1 to n do id[i]:=i; //

fillchar(ref,sizeof(ref),0); //

m:=0; a[0]:=0; //

for i:=1 to n do a[i]:=b[n+1-i];//恢復原陣列

qsort_golarge(1,n);//與上同理

for i:=1 to n do

if a[i]<>a[i-1] then

begin

inc(m);

ref[id[i]]:=m;

endelse ref[id[i]]:=m;

fillchar(c,sizeof(c),0);

for i:=1 to n do

begin

update(ref[i]);

g[n-i+1]:=i-query(ref[i]);

end;

end;

procedure calc;

var i:longint;

begin

ans:=0;

for i:=1 to n do inc(ans,(f[i]*g[i]));//即計算我們所求的sigma(i=1,n) f[i]*g[i]

end;

procedure print;

begin

writeln(ans);

end;

begin

init;//初始化

ca_front;//計算(ica_behind;//計算(jcalc;//計算方案總數

print;//輸出

end.

樹狀陣列求逆序對數小白講解 poj2299

求逆序對數 最進剛剛學習的樹狀陣列,一直感覺沒啥用處,沒想到根據樹狀陣列的特殊結構求逆序對數還是挺方便的 題目鏈結 題意就是求逆序對 給了n個數,但是數比較分散,所以我們需要用離散化一下,把分散的數轉化為為緊湊而且好求的數,然後排一下序,之後求逆序數即可 題解 由於給的數比較散,而且我們求逆序數隻需...

樹狀陣列 (離散化 樹狀陣列 求逆序對)

sample test s input 52 3 1 5 4 output 3 題目大意 求逆序對的個數 題目分析 求逆序對有很多方法,比如說用合併排序 分治 樹狀陣列 線段樹,甚至連暴力 氣泡排序 也可以做,但是要注意會不會超時。這裡就講一下樹狀陣列的方法,這一題最有意思的是離散化的方法,這個方法...

HRBUST 2224 逆序對數(樹狀陣列)

給定 n 個數組成的陣列,求其逆序對的總數。逆序對定義為,存在 i,j 滿足 i j 且 a i a j 的二元組的數目。第一行包含乙個整數,表示陣列的項數。接下來的一行,包含 n 個數 2 n 100000 依次表示 a i a i 10 9 輸出一行表示對應的答案。1 3 2 5 4 對於乙個從...