题目链接:https://www.luogu.org/problemnew/show/P2468

知识点:  可持久化线段树、二分、前缀和

解题思路:

  对于 \(R, C \le 200, M \le 200,000\) 的数据,先处理出前缀和,然后二分取出的数中最小的数。细节请参考 \(solve2()\) 函数。

  对于 \(R=1,C \le 500,000,M \le 20,000\) 的数据,维护一棵记录 \([1,1000]\) 的数在各个历史版本的个数和相应的总和的可持久化线段树,将一行上各列的数依序更新进去。细节请参考 \(solve2()\) 及相关函数。

AC代码:

 #include <bits/stdc++.h>

 using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int maxc=; int sum[maxc*];//记录总和
int has[maxc*];//记录出现次数
int lson[maxc*],rson[maxc*],T[maxc*];
int tot;
int p1[maxc];
void build(int l,int r,int &rt){
rt=++tot;
sum[rt]=has[rt]=;
if(l==r) return;
int m=(l+r)>>;
build(l,m,lson[rt]);
build(m+,r,rson[rt]);
}
void update(int last,int p,int l,int r,int &rt){
rt=++tot;
lson[rt] = lson[last];
rson[rt] = rson[last];
has[rt] = has[last] + ;
sum[rt] = sum[last] + p;
if (l == r) return;
int m = (l + r) >> ;
if (p <= m) update(lson[last], p, l, m, lson[rt]);
else update(rson[last], p, m + , r, rson[rt]);
}
//用一种类似二分的方式来查询
int query(int s,int t,int h,int l,int r){
int ret=;
while(l<r){
int m=(l+r)>>;
int rch=sum[rson[t]]-sum[rson[s]];//优先用右子树(因为其上的数字较大)
if(rch<h)//如果只用右子树仍然不够,则直接加上右子树的总和,再查询左子树
ret+=has[rson[t]]-has[rson[s]],h-=rch,s=lson[s],t=lson[t],r=m;
else//否则查询右子树
s=rson[s],t=rson[t],l=m+;
}
ret+=(h-)/l+;//答案修正
return ret;
}
void solve1(int R,int C,int M){
build(,,T[]);
for(int i=;i<=C;i++){
scanf("%d",&p1[i]);
update(T[i-],p1[i],,,T[i]);
}
int x1,y1,x2,y2,h;
for(int i=;i<M;i++){
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&h);
if(sum[T[y2]]-sum[T[y1-]]<h) printf("Poor QLW\n");
else
printf("%d\n",query(T[y1-],T[y2],h,,));
}
} int p[][];
int have[][][];//have[x][y][k]: 代表p矩阵中在点(x,y)左上角的子矩阵里大于等于k的数的个数
int height[][][];//height[x][y][k]: 代表p矩阵中在点(x,y)左上角的子矩阵里大于等于k的数的总和
int get_have(int x1,int y1,int x2,int y2,int ind){
return have[x2][y2][ind]-have[x1][y2][ind]-have[x2][y1][ind]+have[x1][y1][ind];
}
int get_height(int x1,int y1,int x2,int y2,int ind){
return height[x2][y2][ind]-height[x1][y2][ind]-height[x2][y1][ind]+height[x1][y1][ind];
}
void solve2(int R,int C,int M){
for(int i=;i<=R;i++){
for(int j=;j<=C;j++)
scanf("%d",&p[i][j]);
}
for(int i=;i>=;i--){
for(int x=;x<=R;x++){
for(int y=;y<=C;y++){
//转移
height[x][y][i]=height[x-][y][i]+height[x][y-][i]-height[x-][y-][i]+(p[x][y]>=i?p[x][y]:);
have[x][y][i]=have[x-][y][i]+have[x][y-][i]-have[x-][y-][i]+(p[x][y]>=i?:);
}
}
}
int x1,y1,x2,y2;
int h;
while(M--){
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&h);
int l=,r=;//二分取出来的数中最小的数,此处 r 如果没有初始化为 1001 的话会 WA 一个点
int ans=-;
for(int i=;i<;i++){
int m=(l+r)>>;
int tmp=get_height(x1-,y1-,x2,y2,m);
if(tmp>=h)
l=m,ans=get_have(x1-,y1-,x2,y2,m)-(tmp-h)/m;//减掉多余的部分
else
r=m;
}
if(ans==-) printf("Poor QLW\n");
else printf("%d\n",ans);
}
} int main(){
// freopen("in.txt","r",stdin);
int R,C,M;
scanf("%d%d%d",&R,&C,&M);
if(R==) solve1(R,C,M);
else solve2(R,C,M);
return ;
}

洛谷P2468 粟粟的书架的更多相关文章

  1. 洛谷P2468 [SDOI2010]粟粟的书架

    来了来了,随便拽一道题写题解[大雾] 最近发现自己基础奇差于是开始复习之前学过的东西,正好主席树我几乎完全没学会,然后打开洛谷试炼场… 发现了这么一道二合一的题. 这道题其实分成两个部分,前50%是一 ...

  2. 洛谷P2468 [SDOI2010]粟粟的书架(二分答案 前缀和 主席树)

    题意 题目链接 给出一个矩形,每个点都有一些值,每次询问一个子矩阵最少需要拿几个数才能构成给出的值 Sol 这题是真坑啊.. 首先出题人强行把两个题拼到了一起, 对于前$50 \%$的数据,考虑二分答 ...

  3. 洛谷P2468 SDOI 2010 粟粟的书架

    题意:给你一个矩形书架,每个点是这本书的页数,每次询问(x1,y1)(x2,y2)这个小矩形里最少需要取几本书使得页数和等于Hi. 题解:小数据二位前缀和预处理+二分答案,大数据一行所以用主席树做,感 ...

  4. 洛咕 P2468 [SDOI2010]粟粟的书架

    强行二合一啊... 前面直接二分最小值,二维前缀和.后面用主席树查最小值.注意要写\(nlogn\). // luogu-judger-enable-o2 #include<bits/stdc+ ...

  5. 洛谷$P$2468 粟粟的书架 $[SDOI2010]$ 主席树

    正解:主席树 解题报告: 传送门! 题目大意是说,给定一个矩形,然后每次会给一个,这个大矩形中的一个小矩形,询问从小矩形中最少选多少个数字能满足它们之和大于等于给定数字$x$ 看起来很神的样子,完全不 ...

  6. 洛谷 题解 P2676 【超级书架】

    题解 P2676 [超级书架] 这题就只是一个从大到小的排序而已,用"sort"函数 再用"while"判断奶牛塔的高度是否比书架高度要高 送上代码: #inc ...

  7. BZOJ1926:[SDOI2010]粟粟的书架——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1926 https://www.luogu.org/problemnew/show/P2468 幸福幼 ...

  8. 【BZOJ-1926】粟粟的书架 二分 + 前缀和 + 主席树

    1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec  Memory Limit: 552 MBSubmit: 616  Solved: 238[Submit][Statu ...

  9. 【BZOJ1926】粟粟的书架(主席树,前缀和)

    [BZOJ1926]粟粟的书架(主席树,前缀和) 题面 Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co ...

随机推荐

  1. XEP-0198:流管理

    ------------恢复内容开始------------ 原文来自:https://xmpp.org/extensions/xep-0198.html,只翻译了技术方面的内容. 摘要:这个规范定义 ...

  2. 【集群实战】sersync

    1. sersync介绍 sersync功能: 实时同步: sersync组成: sersync==inotify+rsync inotify: 监控某个目录下面"文件/目录"是否 ...

  3. bootstrap-内联文本元素-小号文本

    说明 使用 <small> 标签包裹,其内的文本将被设置为父容器字体大小的 85% 示例 <!DOCTYPE html> <html lang="zh-CN&q ...

  4. 图论--2-SAT--详解

    问题描述: 现有一个由N个布尔值组成的序列A,给出一些限制关系,比如A[x]AND A[y]=0.A[x] OR A[y] OR A[z]=1等,要确定A[0..N-1]的值,使得其满足所有限制关系. ...

  5. Gitlab常规操作

    一.Git和SVN的区别 和SVN类似,Git是一个版本控制系统(Version Control System,VCS),不同的是SVN为集中式版本控制系统,为单一的集中管理的服务器,保存所有文件的修 ...

  6. E. Yet Another Task with Queens(分类思想)

    \(\color{Red}{描述}\) \(在n*n的棋盘上有m个K皇后,每个皇后可能被来自8个方向的其他皇后攻击\) \(每个皇后只可能被(0-8)只皇后攻击,分别求出被(0-8)只皇后攻击的皇后数 ...

  7. GIL-Guilds(黑白灰染色)

    传送门门门门门咩咩咩咩咩咩咩咩咩咩咩咩 \(这题真是扯谈!!!\) \(灰色很高级是吧,但是题目没要你把颜色全部用上去啊!!!\) \(黑色或者白色只有一个条件,但灰色需要和所有三种颜色都相邻.这么难 ...

  8. 201771030125-王英雪 实验一 软件工程准备一<构建之法与博客首秀>

    项目 内容 班级博客 点我呀! 作业要求 看这里! 课程学习目标 提出三个问题并以写博客的形式记录下来 参考文献 现代软件工程讲义 三个问题 问题一:软件工程究竟是什么? 在现代软件工程讲义一书中给出 ...

  9. Unity2019.3缺少Cinemachine插件/AssetStore搜索不到

    Unity2019.1版本都还自带Cinemachine,到2019.3就没有了(原因暂时未知),PackageManager里没有,到资源商店里搜索也找不到 解决方法: Windows>Pac ...

  10. python 读取矢量文件

    #导入包 from osgeo import ogr #打开文件(False - read only, True - read/write) filename = "文件名.shp" ...