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

版权声明:Fashion Education https://blog.csdn.net/ModestCoder_/article/details/82800694

原题传送门
题目背景
给定长度为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.

猜你喜欢

转载自blog.csdn.net/ModestCoder_/article/details/82800694