题目链接: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. Scala的Higher-Kinded类型

    Scala的Higher-Kinded类型 Higher-Kinded从字面意思上看是更高级的分类,也就是更高一级的抽象.我们先看个例子. 如果我们要在scala中实现一个对Seq[Int]的sum方 ...

  2. JDK12的五大重要新特性

    文章目录 JDK12的五大重要新特性 引入JVM常量API 扩展了switch语句 支持Unicode 11.0 为日本Reiwa Era提供了方形字符支持 NumberFormat增加了对以紧凑格式 ...

  3. 使用Spring Boot搭建你的第一个应用程序

    文章目录 依赖配置 main程序配置 MVC配置 安全配置 存储 Web 页面和Controller 异常处理 测试 结论 Spring Boot是Spring平台的约定式的应用框架,使用Spring ...

  4. Hyperledger Fabric基础知识

    文章目录 什么是Hyperledger Fabric? Hyperledger架构是怎么工作的? Hyperledger交易如何执行 总结 Hyperledger Fabric基础知识 本文我们会介绍 ...

  5. memcached 原子性操作 CAS模式

    2019独角兽企业重金招聘Python工程师标准>>> 应用场景分析: 如原来MEMCACHED中的KES的内容为A,客户端C1和客户端C2都把A取了出来,C1往准备往其中加B,C2 ...

  6. Codeforces Round #623 (Div. 2, based on VK Cup 2019-2020 - Elimination Round, Engine) C. Restoring

    C. Restoring Permutation time limit per test1 second memory limit per test256 megabytes inputstandar ...

  7. 学习HTML

    前端三剑客:HTML.CSS.JavaScript.现在就开始学习HTML啦. 学习资源:http://www.freecodecamp.cn/ 学习笔记: h1,head1,一级标题 <h1& ...

  8. 用纯css、JavaScript、jQuery简单的轮播图

    完成一个可以自动切换或点击数字的轮播图 HTML代码只需要一个div 包含着一个图片和一个列表,我们主要的思路就是通过点击相应的数字,改变图片的 路径. 有4张图片都在img文件夹里,名称为  img ...

  9. LTE无线网络优化简介

    LTE无线网络优化特点 覆盖和质量的估计参数不同 TD-LTE使用RSPP.RSRQ.SINR进行覆盖和质量的评估. 影响覆盖问题的因素不同 工作频段的不同,导致覆盖范围的差异显著:需要考虑天线模式对 ...

  10. [hdu5319]二进制表示,简单模拟

    题意:给一个矩形,矩形里面画了4种符号,'.'表示没画线,'R'表示画了红线,'B'表示画了蓝线,'G'表示红线和蓝线同时画了,并且矩形主对角线上只能画红线,副对角线上只能画蓝线,问最少画多少条线才能 ...