SDOI2010 粟粟的书架 lg2468(可持久化,前缀和)
题面见https://www.luogu.org/problemnew/show/P2468
然后这道题属于合二为一题,看一眼数据范围就能发现
首先我们先考虑50分,二维前缀和维护一下(反正我不记得公式,手推了半天)
tot[i][j][k]表示矩阵(1,1)到(i,j)中数值大等于k的总和
num[i][j][k]表示矩阵(1,1)到(i,j)中数值大等于k的个数
那么做法也就显而易见了,二分k的值进行check
最后注意一个小问题,就是有可能一个k值有多个点,而我不需要全选就能满足条件,这个可以自行理解一下
后百分之五十,一开始口胡了一个一维前缀和的做法,貌似是两个log,然而我在学可持久化数据结构,不能偷懒
思考了一下,开一棵权值线段树,把它变成主席树,根x代表插入了第x个数后的情况
然后建树,更新都是裸的操作
关于查询我的想法我写在了代码里,想不通的可以看一下
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int w=,f=;
char ch=getchar();
while(ch<''||ch>''){
if(ch=='-') f=-;
ch=getchar();
}
while(ch>=''&&ch<=''){
w=(w<<)+(w<<)+ch-;
ch=getchar();
}
return w*f;
}
int n,m,q,a[][],tot[][][],num[][][],ans,cnt,root[],b[];
int get_sum(int x1,int y1,int x2,int y2,int k,int f)
{
if(f==)return tot[x2][y2][k]-tot[x2][y1-][k]-tot[x1-][y2][k]+tot[x1-][y1-][k];
else return num[x2][y2][k]-num[x2][y1-][k]-num[x1-][y2][k]+num[x1-][y1-][k];
}
inline void work2(){//二维前缀和大力维护,口胡了一下写在上面了,就不多解释了,着重看主席树
int i,j,k,maxx=;
for(i=;i<=n;i++){
for(j=;j<=m;j++){
a[i][j]=read();maxx=max(maxx,a[i][j]);
}
}
for(k=;k<=maxx;k++){
for(i=;i<=n;i++){
for(j=;j<=m;j++){
tot[i][j][k]=tot[i-][j][k]+tot[i][j-][k]-tot[i-][j-][k]+(a[i][j]>=k)*a[i][j];
num[i][j][k]=num[i-][j][k]+num[i][j-][k]-num[i-][j-][k]+(a[i][j]>=k);
}
}
}
while(q--){
int x1,y1,x2,y2,h;
x1=read();y1=read();x2=read();y2=read();h=read();
if(get_sum(x1,y1,x2,y2,,)<h) puts("Poor QLW");
else{
int l=,r=maxx+;ans=-;
while(l<=r){
int mid=(l+r)>>;
if(get_sum(x1,y1,x2,y2,mid,)>=h){
ans=mid;l=mid+;
}
else r=mid-;
}
printf("%d\n",get_sum(x1,y1,x2,y2,ans,)-(get_sum(x1,y1,x2,y2,ans,)-h)/ans);
}
}
}
struct Node{
int ls,rs,sum,size;
}st[];
inline int build(int l,int r){
int pos=cnt++;
if(l==r) return pos;
int mid=(l+r)>>;
st[pos].ls=build(l,mid);
st[pos].rs=build(mid+,r);
return pos;
}//常规建树
inline int update(int tim,int l,int r,int x){//tim表示历史版本,l,r为范围,x为我当前插入的数
int pos=cnt++;
st[pos]=st[tim];st[pos].size++;st[pos].sum+=x;//这个节点的size+1,sum+=x
if(l==r) return pos;//到叶子了,大力返回就好
int mid=(l+r)>>;
if(x<=mid) st[pos].ls=update(st[tim].ls,l,mid,x);
else st[pos].rs=update(st[tim].rs,mid+,r,x);
return pos;
}
inline int query(int l,int r,int fir,int sec,int w){//具体解释见下方
if(l==r) return (w-)/l+;//可能不会整除,就这么处理一下就好了
int mid=(l+r)>>;int x=st[st[sec].rs].sum-st[st[fir].rs].sum;
if(w<=x) return query(mid+,r,st[fir].rs,st[sec].rs,w);
else return st[st[sec].rs].size-st[st[fir].rs].size+query(l,mid,st[fir].ls,st[sec].ls,w-x);
}
/*
这棵主席树是基于权值线段树的,权值的范围只有1k
主席树维护了历史版本的权值线段树上的size和sum
然后关于建树和更新都没什么新意
查询这个我一开始不能很好的理解,那么我现在稍微解释一下我的思路
首先l,r,fir,sec,w分别表示区间,版本号,还需要多少值
然后大多数题查询的时候都是向左子树查一下,比一下大小
这里查右子树是因为这是一棵权值线段树,我们希望尽量少地选点,也就意味着选的数要尽可能大
那么能选右子树(也就是值更大的点),当然选大的啊
如果右子树总和够,就往右子树走,不够的话,算上右子树,往左子树走
*/
inline void work1()
{
int maxw=-1e9-;
for(int i=;i<=m;i++) b[i]=read(),maxw=max(b[i],maxw);
root[]=build(,maxw+);
for(int i=;i<=m;i++) root[i]=update(root[i-],,maxw,b[i]);
for(int i=;i<=q;i++)
{
int y1,y2,h;y1=read(),y1=root[read()-],y2=read(),y2=root[read()],h=read();
if(st[y2].sum-st[y1].sum<h){puts("Poor QLW");continue;}
printf("%d\n",query(,maxw,y1,y2,h));
}
}
int main(){
n=read();m=read();q=read();
if(n!=){//合二为一辣鸡题
work2();
}
else work1();
return ;
}
SDOI2010 粟粟的书架 lg2468(可持久化,前缀和)的更多相关文章
- bzoj1926[Sdoi2010]粟粟的书架 二分 主席树
1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec Memory Limit: 552 MBSubmit: 1064 Solved: 421[Submit][Stat ...
- bzoj 1926: [Sdoi2010]粟粟的书架 (主席树+二分)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1926 题面; 1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Se ...
- [bzoj1926][Sdoi2010]粟粟的书架_二分_主席树
粟粟的书架 bzoj-1926 Sdoi-2010 题目大意:题目链接 注释:略 想法:分成两个题 前面的我们可以二分,直接二分出来检验即可. 对于R=1的,相当一个数列,我们在上面建立主席树. 然后 ...
- Bzoj 1926: [Sdoi2010]粟粟的书架(二分答案+乱搞+主席树)
1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec Memory Limit: 552 MB Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱 ...
- [SDOI2010]粟粟的书架 [主席树]
[SDOI2010]粟粟的书架 考虑暴力怎么做 显然是提取出来 (x2-x1+1)*(y2-y1+1) 个数字拿出来 然后从大到小排序 然后就可以按次取数了- 然而接下来看数据范围 \(50\%\ r ...
- [BZOJ1926][SDOI2010]粟粟的书架
BZOJ Luogu Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Cormen 的文章.粟粟家中有一个 R ...
- BZOJ1926[Sdoi2010]粟粟的书架——二分答案+主席树
题目描述 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co rmen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位 ...
- 【刷题】BZOJ 1926 [Sdoi2010]粟粟的书架
Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Cormen 的文章.粟粟家中有一个 R行C 列的巨型书架,书 ...
- BZOJ1926:[SDOI2010]粟粟的书架——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1926 https://www.luogu.org/problemnew/show/P2468 幸福幼 ...
- 【BZOJ1926】【SDOI2010】粟粟的书架 [主席树]
粟粟的书架 Time Limit: 30 Sec Memory Limit: 552 MB[Submit][Status][Discuss] Description 幸福幼儿园 B29 班的粟粟是一 ...
随机推荐
- 8.python内置模块之random模块简介
Python中的random模块用于生成随机数. 常用的7个函数: 1.random.random():返回一个[0,1)之间的随机浮点值(双精度) 2.random.uniform(a,b):返回[ ...
- MySQL基础(6) | check约束
MySQL基础(6) | check约束 前言 在一些情况下,我们需要字段在指定范围的输入, 例如:性别只能输入 '男'或者'女',余额只能大于0等条件, 我们除了在程序上控制以外,我们还能使用 CH ...
- idea 编译报错 Build completed with 1 error and 0 warnings in 2 s 113 ms
settings里java compiler改成正确版本 project structure里同样如此
- 清北学堂—2020.1提高储备营—Day 3(图论初步(二))
qbxt Day 3 --2020.1.19 济南 主讲:李奥 目录一览 1.图论(kruskal算法,最短路径算法,拓扑排序) 总知识点:图论 一.kruskal算法 1.目的:求图的最小生成树 2 ...
- Spring cloud微服务安全实战 最新完整教程
课程资料获取链接:点击这里 采用流行的微服务架构开发,应用程序访问安全将会面临更多更复杂的挑战,尤其是开发者最关心的三大问题:认证授权.可用性.可视化.本课程从简单的API安全入手,过渡到复杂的微服务 ...
- MySQL 8 用户定义函数
MySQL Server可以通过创建或者加载UDFs(User-Defined Functions)来扩展服务器功能. 通过CREATE FUNCTION语句加载 UDF,比如: CREATE FUN ...
- 数据库中间件DBLE学习(二) 学习配置schema.xml
前言 一边有一个经常引诱我让我"娱乐至死"的视频,还有一个不停"鞭策"我让我快点学习的大BOSS.正是有这两种极端的爱才让我常常在自信中明白自己努力的方向.嗯, ...
- 使用高精度计算斐波那契数列 c++
使用高精度计算斐波那契数列 非高精度 Code(Non-high accuracy) 这是不用高精度的代码 #include<bits/stdc++.h> using namespace ...
- 【剑指Offer】61、把二叉树打印成多行
题目描述 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 题解一:BFS public static ArrayList<ArrayList<Integer>> ...
- 【计算语言学实验】基于 Skip-Gram with Negative Sampling (SGNS) 的汉语词向量学习和评估
一.概述 训练语料来源:维基媒体 https://dumps.wikimedia.org/backup-index.html 汉语数据 用word2vec训练词向量,并用所学得的词向量,计算 pku_ ...