链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1926

题面;

1926: [Sdoi2010]粟粟的书架

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 1669  Solved: 618
[Submit][Status][Discuss]

Description

幸福幼儿园 B29 班的粟粟是一个聪明机灵、乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co
rmen 的文章。粟粟家中有一个 R行C 列的巨型书架,书架的每一个位置都摆有一本书,上数第i 行、左数第j 列
摆放的书有Pi,j页厚。粟粟每天除了读书之外,还有一件必不可少的工作就是摘苹果,她每天必须摘取一个指定的
苹果。粟粟家果树上的苹果有的高、有的低,但无论如何凭粟粟自己的个头都难以摘到。不过她发现, 如果在脚
下放上几本书,就可以够着苹果;她同时注意到,对于第 i 天指定的那个苹果,只要她脚下放置书的总页数之和
不低于Hi,就一定能够摘到。由于书架内的书过多,父母担心粟粟一天内就把所有书看完而耽误了上幼儿园,于是
每天只允许粟粟在一个特定区域内拿书。这个区域是一个矩形,第 i 天给定区域的左上角是上数第 x1i行的左数
第 y1i本书,右下角是上数第 x2i行的左数第y2i本书。换句话说,粟粟在这一天,只能在这﹙x2i-x1i+1﹚×﹙
y2i-y1i+1﹚本书中挑选若干本垫在脚下,摘取苹果。粟粟每次取书时都能及时放回原位,并且她的书架不会再
撤下书目或换上新书,摘苹果的任务会一直持续 M天。给出每本书籍的页数和每天的区域限制及采摘要求,请你告
诉粟粟,她每天至少拿取多少本书,就可以摘到当天指定的苹果。

Input

第一行是三个正整数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 Output

6
15
2
Poor QLW
9
1
3

HINT

对于 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
思路:
一开始怎么都想不到怎么写,这道题主要就是要发现数据范围的特殊性,对于R,C<=200的数据我们可以前缀和维护,每次二分最小值,对于R=1的情况其实就是一维的数组,我们直接用主席树维护,然后二分最小值。
s[i][j][k] 代表  从(1,1) 到 (i,j)大于k的数的值之和
t[i][j][k] 代表 从(1,1)到(i,j) 大于k的数的个数
 
我们假设k为最小值,那么肯定k越大s[i][j][k]越小,那么就可以二分k找到最小的大于h的k。
 
实现代码:
#include<bits/stdc++.h>
using namespace std;
const int M = 5e5+;
int ls[M*],rs[M*],sum[M*],idx,rt[M],num[M*],n,m;
int mp[][],s[][][],t[][][],v[];
void update(int old,int &k,int p,int c,int l,int r){
k = ++idx;
ls[k] = ls[old]; rs[k] = rs[old];
sum[k] = sum[old] + c;
num[k] = num[old] + ;
if(l == r) return ;
int mid = (l + r) >> ;
if(p <= mid) update(ls[old],ls[k],p,c,l,mid);
else update(rs[old],rs[k],p,c,mid+,r);
} int query(int old,int k,int L,int R,int l,int r){
if(L <= l&&R >= r){
return sum[k] - sum[old];
}
int mid = (l + r) >> ;
int ret = ;
if(L <= mid) ret += query(ls[old],ls[k],L,R,l,mid);
if(R > mid) ret += query(rs[old],rs[k],L,R,mid+,r);
return ret;
} int ask(int old,int k,int L,int R,int l,int r){
if(L <= l&&R >= r){
return num[k] - num[old];
}
int mid = (l + r) >> ;
int ret = ;
if(L <= mid) ret += ask(ls[old],ls[k],L,R,l,mid);
if(R > mid) ret += ask(rs[old],rs[k],L,R,mid+,r);
return ret;
} void init(){
for(int i = ;i <= n;i ++){
for(int j = ;j <= m;j ++){
for(int k = ;k <= ;k ++){
t[i][j][k] = t[i-][j][k]+t[i][j-][k]-t[i-][j-][k];
}
t[i][j][mp[i][j]] += ;
}
}
for(int i = ;i <= n;i ++){
for(int j = ;j <= m;j ++){
for(int k = ;k >= ;k --){
s[i][j][k] = s[i][j][k+]+t[i][j][k]*k;
t[i][j][k] += t[i][j][k+];
}
}
}
} int getsum(int k,int x1,int y1,int x2,int y2){
//cout<<s[x2][y2][k]<<" "<<s[x1-1][y1-1][k]<<" "<<s[x1-1][y2][k]<<endl;
int num = s[x2][y2][k] + s[x1-][y1-][k] - s[x1-][y2][k] - s[x2][y1-][k];
return num;
} int getnum(int k,int x1,int y1,int x2,int y2){
int num = t[x2][y2][k] + t[x1-][y1-][k] - t[x1-][y2][k] - t[x2][y1-][k];
return num;
} int main()
{
int p,x1,x2,y1,y2,h;
scanf("%d%d%d",&n,&m,&p);
for(int i = ;i <= n;i ++){
for(int j = ;j <= m;j ++){
cin>>mp[i][j],v[mp[i][j]]++;
}
}
if(n <= &&m <= ){
init();
for(int i = ;i <= p;i ++){
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&h);
int l = ,r = ,ans = ,id=-;
while(l <= r){
int mid = (l + r) >> ;
int num = getsum(mid,x1,y1,x2,y2);
if(num >= h){
id = mid,ans = num,l = mid+;
}
else r = mid-;
}
if(id == -){
printf("Poor QLW\n"); continue;
}
int cur = getnum(id,x1,y1,x2,y2);
while(ans-id>=h){
ans-=id; cur--;
}
printf("%d\n",cur);
}
}
else{
for(int i = ;i <= m;i ++)
update(rt[i-],rt[i],mp[][i],mp[][i],,M);
for(int i = ;i <= p;i ++){
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&h);
int l = ,r = ,ans = ,id = -;
while(l <= r){
int mid = (l + r) >> ;
int num = query(rt[y1-],rt[y2],mid,M,,M);
if(num >= h){
id = mid,ans = num,l = mid+;
}
else r = mid-;
}
if(id == -){
printf("Poor QLW\n"); continue;
}
int cur = ask(rt[y1-],rt[y2],id,M,,M);
while(ans-id>=h){
ans-=id; cur--;
}
printf("%d\n",cur);
}
}
return ;
}
 

bzoj 1926: [Sdoi2010]粟粟的书架 (主席树+二分)的更多相关文章

  1. BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案)

    BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案) 题意 : 给你一个长为\(R\)宽为\(C\)的矩阵,第\(i\)行\(j\)列的数为\(P_{i,j}\). 有\(m\)次 ...

  2. BZOJ.1926.[SDOI2010]粟粟的书架(前缀和 主席树 二分)

    题目链接 题意: 在给定矩形区域内找出最少的数,满足和>=k.输出数的个数.两种数据范围. 0~50 注意到(真没注意到...)P[i,j]<=1000,我们可以利用前缀和预处理. num ...

  3. 2018湘潭邀请赛C题(主席树+二分)

    题目地址:https://www.icpc.camp/contests/6CP5W4knRaIRgU 比赛的时候知道这题是用主席树+二分,可是当时没有学主席树,就连有模板都不敢套,因为代码实在是太长了 ...

  4. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  5. HDU - 4866 主席树 二分

    题意:在x轴\([1,X]\)内的上空分布有n个占据空间\([L_i,R_i]\),高度\(D_i\)的线段,射中线段的得分为其高度,每次询问从x轴的\(x\)往上空射的最近k个线段的总得分,具体得分 ...

  6. POJ 6621: K-th Closest Distance(主席树 + 二分)

    K-th Closest Distance Time Limit: 20000/15000 MS (Java/Others)    Memory Limit: 524288/524288 K (Jav ...

  7. HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)

    HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分) 传送门:http://acm.hdu.edu.cn/showproblem.php? ...

  8. Bzoj 1926: [Sdoi2010]粟粟的书架(二分答案+乱搞+主席树)

    1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec Memory Limit: 552 MB Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱 ...

  9. 【刷题】BZOJ 1926 [Sdoi2010]粟粟的书架

    Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Cormen 的文章.粟粟家中有一个 R行C 列的巨型书架,书 ...

随机推荐

  1. Java学习点滴——Class和反射

    基于<Java编程思想>第四版 前言 我们要操作一个类实例对象时,一般都要先知道这个类有哪些方法或者成员变量.反射就是在我们不知道这个类有哪些方法或成员变量时,使用特定方式得到类的这些信息 ...

  2. Python笔记-高级特性

    1.迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 如果要迭代value,可以用for value in d ...

  3. C#标识符与关键字

    标识符是指在程序中用来表示实物的单词,是分配给类型(类.结构.枚举.接口或委托).成员.变量或命名空间的名称.有效标识符必须遵循以下原则: 标识符不能以数字开头也不能包含空格: 标识符可以包含大小写字 ...

  4. 【视频】设计模式(C++)视频讲解

    设计模式(C++) 视频网址: http://www.qghkt.com/ 设计模式(C++)视频地址: https://ke.qq.com/course/318637?tuin=a508ea62 目 ...

  5. Mysql--alter命令小特点

    以下命令均在mysql命令行下执行.1. 修改表名称有2种方法,mysql命令行,没有区分大小写,方法1:mysql>ALTER TABLE 表名l RENAME TO 表名2; 方法2:mys ...

  6. VMware小记

    博主最近不知道为啥,有点手贱,折腾虚拟机. 然后某天,突然发现虚拟机连不上网,ping物理机,返回结果是不可达. 后来尝试各种手段,注意到VMware Network Adapter VMnet8和  ...

  7. logback日志框架的简单使用

    1.首先在maven中增加依赖 <dependency> <groupId>ch.qos.logback</groupId> <artifactId>l ...

  8. js 秒数格式化

    function formatSeconds(value) { var theTime = parseInt(value);// 秒 var theTime1 = 0;// 分 var theTime ...

  9. 使用FreeCookies 控制浏览器cookies及修改http响应内容

    FreeCookies 插件安装 :您的计算机需要已经安装Fiddler (如未安装,请至官网下载安装 http://docs.telerik.com/fiddler/configure-fiddle ...

  10. MySQL操作(备份很重要)

    文档一: --修改用户密码的命令 mysqladmin -uroot -proot123 password mysql123 --登录mysql数据库的命令 mysql -uroot -proot12 ...