SDOI2010 粟粟的書架 整體二分

2021-09-12 22:24:40 字數 4612 閱讀 7581

description

第一行是三個正整數r,c,m。

接下來是乙個r行c列的矩陣,從上到下、從左向右依次給出了每本書的頁數pi,j。

接下來m行,第i行給出正整數x1i,y1i,x2i,y2i,hi,表示第i天的指定區域是﹙x1i,y1i﹚與﹙x2i,y2i﹚間

的矩形,總頁數之和要求不低於hi。

保證1≤x1i≤x2i≤r,1≤y1i≤y2i≤c。

output

有m行,第i 行回答粟粟在第 i 天時為摘到蘋果至少需要 拿取多少本書。如果即使取走所有書都無法摘到蘋果,

則在該行輸出「poor qlw」 (不含引號)。

sample input

5 5 7

14 15 9 26 53

58 9 7 9 32

38 46 26 43 38

32 7 9 50 28

8 41 9 7 17

1 2 5 3 139

3 1 5 5 399

3 3 4 5 91

4 1 4 1 33

1 3 5 4 185

3 3 4 3 23

3 1 3 3 108

sample output615

2poor qlw91

3hint

對於 10%的資料,滿足 r, c≤10;

對於 20%的資料,滿足 r, c≤40;

對於 50%的資料,滿足 r, c≤200,m≤200,000;

另有 50%的資料,滿足 r=1,c≤500,000,m≤20,000;

對於 100%的資料,滿足 1≤pi,j≤1,000,1≤hi≤2,000,000,000

貪心選最大的,排序後從大到小加書,可以整體二分,加前一半,看是否滿足h,滿足分到前面,否則算上影響,分到後面.(兩類資料分別用樹狀陣列和二維樹狀陣列維護)

problem:

1926

user: wine

language: c++

result: accepted

time:

16244 ms

memory:

24076 kb**

****

****

****

****

****

****

****

****

****

****

****

****

****

****

****

**/#include

#include

#include

#include

using

namespace std;

void

read

(int

&x)#define maxn 510000

#define maxm 201000

#define lb(x) (x&-x)

int r,c,m,tot;

struct ea[maxn]

;bool

cmp(

const e &a,

const e &b)

struct que

bool inside (e a)

}q[maxm]

,t[maxm]

;bool

cmp_id

(const que &a,

const que &b)

namespace risnotone

intsum

(int x,

int y)

void

_add

(int x,

int y,

int v)

int_sum

(int x,

int y)

intsum

(que a)

int_sum

(que a)

void

slove

(int l,

int r,

int l,

int r)

int m =

(l+r)

>>

1,tt = l;

for(

int i = l; i <= m; i++

)for

(int i = l; i <= r; i++)if

(q[i]

.hi >0)

else q[i]

.p =

1,tt++;}

else q[i]

.p =

1,tt++

;for

(int i = l; i <= m; i++

)int s = l,e = tt;

for(

int i = l; i <= r; i++

) t[q[i]

.p?s++

:e++

]= q[i]

;for

(int i = l; i <= r; i++

) q[i]

= t[i]

;slove

(l,tt-

1,l,m)

;slove

(tt,r,m+

1,r);}

void

work()

for(

int i =

1; i <= m; i++

) q[i]

.init

(i);

sort

(a+1

,a+tot+

1,cmp)

;slove(1

,m,1

,tot)

;sort

(q+1

,q+m+

1,cmp_id)

;for

(int i =

1; i <= m; i++)if

(q[i]

.hi <=0)

printf

("%d\n"

,q[i]

.ans)

;else

printf

("poor qlw\n");

}#undef n

}namespace risone

intsum

(int y)

void

_add

(int y,

int v)

int_sum

(int y)

intsum

(que a)

int_sum

(que a)

void

slove

(int l,

int r,

int l,

int r)

int m =

(l+r)

>>

1,tt = l;

for(

int i = l; i <= m; i++

)for

(int i = l; i <= r; i++)if

(q[i]

.hi >0)

else q[i]

.p =

1,tt++;}

else q[i]

.p =

1,tt++

;for

(int i = l; i <= m; i++

)int s = l,e = tt;

for(

int i = l; i <= r; i++

) t[q[i]

.p?s++

:e++

]= q[i]

;for

(int i = l; i <= r; i++

) q[i]

= t[i]

;slove

(l,tt-

1,l,m)

;slove

(tt,r,m+

1,r);}

void

work()

for(

int i =

1; i <= m; i++

) q[i]

.init

(i);

sort

(a+1

,a+tot+

1,cmp)

;slove(1

,m,1

,tot)

;sort

(q+1

,q+m+

1,cmp_id)

;for

(int i =

1; i <= m; i++)if

(q[i]

.hi <=0)

printf

("%d\n"

,q[i]

.ans)

;else

printf

("poor qlw\n");

}#undef n

}int

main()

Sdoi2010 粟粟的書架

主席樹 二分 字首和 time limit 30 sec memory limit 552 mb submit 919 solved 366 submit status discuss 第一行是三個正整數r,c,m。接下來是乙個r行c列的矩陣,從上到下 從左向右依次給出了每本書的頁數pi,j。接下來...

SDOI2010 粟粟的書架

明顯的二合一問題。貪心的想,要個數最少,那麼久從頁數多的開始選。於是對於前50 的資料,可以直接預處理 1x,1y 矩陣內大於等於k的元素個數 元素之和的字首和,然後二分k值來驗證 對於後50 的資料,已經退化為一維情形,若再使用前面的方法會mle 5e51e34 那麼考慮使用主席樹來維護 每個節點...

SDOI2010 粟粟的書架

幸福幼兒園b29班的粟粟是乙個聰明機靈 乖巧可愛的小朋友,她的愛好是畫畫和讀書,尤其喜歡thomas h.cormen的文章。粟粟家中有乙個r行c列的巨型書架,書架的每乙個位置都擺有一本書,上數第i行 左數第j列擺放的書有pi,j頁厚。粟粟每天除了讀書之外,還有一件必不可少的工作就是摘蘋果,她每天必...