题目链接:http://poj.org/problem?id=2481
树状数组裸题,求的是把线段i包含的线段有几条,可以有1个端点重合,但是不可以两个端点都重合,注意判重就好
贴代码
const maxn=100005;
var a,b,c,id,ans:array[0..maxn]of longint;
n:longint;
procedure swap(var x,y:longint);
var t:longint;
begin
t:=x;x:=y;y:=t;
end;
procedure qsort(L,R:longint);
var i,j,mid,mida,midb:longint;
begin
i:=L;j:=R;mid:=random(R-L+1)+L;
mida:=a[mid];midb:=b[mid];
repeat
while (a[i]<mida)or((a[i]=mida)and(b[i]>midb)) do inc(i);
while (a[j]>mida)or((a[j]=mida)and(b[j]<midb)) do dec(j);
if i<=j then begin
swap(a[i],a[j]);swap(b[i],b[j]);swap(id[i],id[j]);
inc(i);dec(j);
end;
until i>j;
if i<R then qsort(i,R);
if L<j then qsort(L,j);
end;
function lowbit(x:longint):longint;
begin
lowbit:=x and (-x);
end;
procedure add(x:longint);
begin
while x<=maxn do
begin
inc(c[x]);
inc(x,lowbit(x));
end;
end;
function query(x:longint):longint;
var s:longint;
begin
s:=0;
while x>=1 do
begin
inc(s,c[x]);
dec(x,lowbit(x));
end;
exit(s);
end;
procedure init;
var i,j:longint;
begin
assign(input,'cows.in');reset(input);
assign(output,'cows.out');rewrite(output);
end;
procedure main;
var i,j,k:longint;
begin
readln(n);
while n<>0 do
begin
for i:=1 to n do readln(a[i],b[i]);
for i:=1 to n do id[i]:=i;
qsort(1,n);a[0]:=maxn;inc(n);a[n]:=maxlongint; id[n]:=maxn;
fillchar(c,sizeof(c),0);
for i:=1 to n do
begin
inc(b[i]);
ans[id[i]]:=query(maxn)-query(b[i]-1);
if (b[i]<>b[i-1])and(i>2)then begin
j:=i-1;
while (j-1>=1)and(a[j-1]=a[j])and(b[j-1]=b[j]) do dec(j);
for k:=j+1 to i-1 do ans[id[k]]:=ans[id[j]];
end;
add(b[i]);
end;
for i:=1 to n-1 do write(ans[i],' ');
writeln;
readln(n);
end;
end;
procedure print;
begin
close(input);close(output);
end;
begin
// init;
main;
// print;
end.
【写的有漏洞的,欢迎路过大神吐槽】
2016/11/14 09:13:10
Ending.