1. 程式人生 > >【題解】LuoGu3660: [USACO17FEB]Why Did the Cow Cross the Road III G

【題解】LuoGu3660: [USACO17FEB]Why Did the Cow Cross the Road III G

原題傳送門 題目背景 給定長度為2N的序列,1~N各處現過2次,i第一次出現位置記為ai,第二次記為bi,求滿足ai<aj<bi<bj的對數 輸入樣例 4 3 2 4 4 1 3 2 1 輸出樣例 3

【題解】 樹狀陣列 以a陣列為關鍵字,從小到大排序,滿足ai<aj 排好序後,線掃一遍,根據ai<aj<bi<bj,每次在答案裡累加query(b[i]-1)-query(a[i]) 然後add操作

Code:

var
    tree,a,b:array[0..1000000] of longint;
    n,i,x,ans:longint;

procedure sort(l,r:longint);
var
    i,j,mid,tmp:longint;

begin
    i := l; j := r;
    mid := a[(l + r) >> 1];
    repeat
        while a[i] < mid do inc(i);
        while a[j] > mid do dec(J);
        if i <= j then
        begin
            tmp := a[i]; a[i] := a[j]; a[j] := tmp;
            tmp := b[i]; b[i] := b[j]; b[j] := tmp;
            inc(i); dec(j);
        end;
    until i > j;
    if i < r then sort(i,r);
    if l < j then sort(l,j);
end;

procedure add(x:longint);

begin
    while x <= (n << 1) do
    begin
        inc(tree[x]);
        inc(x, x and -x);
    end;
end;

function query(x:longint):longint;

begin
    query := 0;
    while x > 0 do
    begin
        inc(query, tree[x]);
        dec(x, x and -x);
    end;
end;

begin
    readln(n);
    for i := 1 to (n << 1) do
    begin
        readln(x);
        if a[x] <> 0 then
            b[x] := i else a[x] := i;
    end;
    sort(1,n);
    for i := 1 to n do
    begin
        inc(ans, query(b[i] - 1) - query(a[i]));
        add(b[i]);
    end;
    writeln(ans);
end.