版权声明: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.