树状数组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.
總結
以上是生活随笔為你收集整理的树状数组c语言模板,【树状数组】Cows (POJ2481) PASCAL 解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言随机迷宫生成方法,[原创]递归随机
- 下一篇: android发送短信指定收件人,and