树状数组c语言模板,【树状数组】Cows (POJ2481) PASCAL 解题报告
【树状数组】Cows
(POJ2481)
Time Limit:1000MS Memory
Limit:65536K
Total Submit:16 Accepted:8
Description
【问题描述】
约翰是一个农民,他养了一群羊,一群很喜欢吃山上的三叶草的羊。所有的三叶草都生长在一条直线上,味道十分美妙。
约翰有N头牛,分别叫牛1到牛N。每头牛都有特别中意的三叶草范围,记为[S,E]——这是直线上的一个区间。不同牛喜欢的三叶草范围之间可能重叠。
有些牛比较强壮,有些牛比较弱小。给定两头牛:牛i和牛j。它们喜欢的三叶草范围分别为[Si, Ei]和[Sj, Ej]。如果Si
<=Sj 并且 Ej <=Ei 并且 Ei-Si
> Ej-Sj,那么就认为牛i比牛j更强壮。
对于每头牛,有多少头牛比它更强壮呢?约翰请你来帮忙。
Input
输入包括多组数据。对于每组数据,第一行是整数N
(1 <= N <=
105),表示牛的头数。接下来N行,第i行有两个整数S和E(0 <= S
< E <= 105),表示牛i喜欢的三叶草区间。
最后一组数据只有0,表示结束。
Output
对于每组测试数据,输出一行,包括n个用空格分开的整数,第i个整数表示比牛i更强壮的牛的数目。
Sample
Input
3
1 2
0 3
3 4
0
Sample
Output
1 0 0
Hint
对于C/C++程序员:数据规模较大,建议采用scanf 和 printf。
请将你的程序在 http://poj.org/problem?id=2481 上提交测试是否能通过!
Source
POJ2481
这题想了好久,也上网看了不少解题报告,都是说“和
数星星 那道题一样”,我却怎么也不明白,而且网上给的程序都是用C语言写的。很是郁闷。
其实这题给出区间边界x,y 可以把他们看成是 横坐标
和 纵坐标。 然后就和 数星星 差不多了
先按
y从大到小排序,y相等的从小到大排序
树状数组的下标为x,把排好序的数组从头到尾扫一遍,把结果储存在另一个数组。
这题我先是超时,检查了好久,竟发现是快排写错了。少了个while循环。
然后又是WA,对两个区间完全相同的情况处理错了。
并且,POJ上是多组数据,而我得到的翻译版本竟是单组数据。。
var
n,max:longint;
a:array[0..100010,1..4]of longint;
f:array[0..100010]of longint;
b:array[0..100010]of longint;
procedure init;
var
i:longint;
begin
for i:=1 to n do
begin
readln(a[i,1],a[i,2]);
inc(a[i,1]);
inc(a[i,2]);
if a[i,2]>max then
max:=a[i,2];
a[i,3]:=i;
end;
end;
procedure
qsort1(x,y:longint);
var
i,j,k1,k2,k:longint;
begin
if x>=y then exit;
i:=x;
j:=y;
k:={random(j-i)+i;}(i+j)div 2;
k1:=a[k,1];
k2:=a[k,2];
while i
begin
while
(a[i,2]>k2)or((a[i,2]=k2)and(a[i,1]
do inc(i);
while
(a[j,2]k1))
do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i);
dec(j);
end;
end;
qsort1(i,y);
qsort1(x,j);
end;
function
find(i:longint):longint;
begin
find:=0;
if i=0 then exit;
while i>0 do
begin
inc(find,f[i]);
i:=i-i and -i;
end;
end;
procedure
add(i:longint);
begin
if i=0 then exit;
while i<=max do
begin
inc(f[i]);
i:=i+i and -i;
end;
end;
procedure main;
var
i,j:longint;
begin
i:=1;
while i<=n do
begin
j:=i;
while
(a[i,2]=a[j,2])and(a[i,1]=a[j,1]) do
begin
if i=j then
a[i,4]:=find(a[i,1])
else a[i,4]:=a[j,4];
add(a[i,1]);
inc(i);
end;
if i=j then inc(i);
end;
end;
procedure print;
var
i:longint;
begin
for i:=1 to n do b[a[i,3]]:=i;
for i:=1 to n do
write(a[b[i],4],' ');
writeln;
end;
begin
randomize;
readln(n);
while n<>0 do
begin
fillchar(a,sizeof(a),0);
fillchar(f,sizeof(f),0);
fillchar(b,sizeof(b),0);
max:=0;
init;
qsort1(1,n);
main;
print;
read(n);
end;
end.
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)