[BZOJ 1926] 粟粟的书架
BZOJ的sillyB评测机各种无故CE,只好去Luogu上A了o(╯□╰)o
Solution:
从数据范围可以发现,这其实是2道题:
(1)一个$R*C$的矩形,每次询问一个子矩形的结果,$R,C\le 200$,$A[i][j]\le 1000$。
(2)一个$C$个数的序列,每次询问一个区间的结果,$C\le 5e5$。
1、前缀和+二分答案
找到此题的数据特点:$A[i][j]$极小,只有1000,使得$O(RC*1000)$的算法可行
于是我们维护1~i,1~j的矩形中大于k的数的个数及它们的总和,从而O(1)得出目标矩形的结果
$cnt[i][j][k]$表示行号在$[1,i]$,列号在$[1,j]$,厚度大于等于$k$的书的数目。
$sum[i][j][k]$表示行号在$[1,i]$,列号在$[1,j]$,厚度大于等于$k$的书的厚度之和。
每一次询问二分最小厚度(最小厚度是否可行具有单调性),求出值$t$,表示满足条件的情况下,最大的最小厚度。
然而由于有相同厚度,因此还要计算出厚度为$t$的书有多少本没有用上。
2、主席树
主席树解决的一类经典问题是求区间第K大的数
其实在这种背景下主席树的应用和线段树的性质关系并不大,可以理解为带了前缀和的二分查找树
由于其处理的区间具有对应关系,于是维护前缀的线段树间是可以相加减的,从而得到当前区间的信息
此题中厚度仅为1000,于是在每个点维护:
$cnt$:该前缀版本中,这个节点对应厚度区间内的书的数量。
$sum$:该前缀版本中,这个节点对应厚度区间内的书的厚度之和。
这样对答案在$root[end]-root[start-1]$的线段树中类似二分查找树地确定是进入左子树还是右子树即可
Code:
#include <bits/stdc++.h> using namespace std; inline int read()
{
char ch;int num,f=0;
while(!isdigit(ch=getchar())) f|=(ch=='-');
num=ch-'0';
while(isdigit(ch=getchar())) num=num*10+ch-'0';
return f?-num:num;
} const int MAXN=205,MAXM=1005;
const int N=5e5+10,M=1e7+10; struct FunSeg
{
int ls,rs,sum,cnt;
}seg[M];
int root[N],S[N],cnt; int n,m,q,dat[MAXN][MAXN],f[MAXN][MAXN][MAXM],g[MAXN][MAXN][MAXM]; int cal_f(int x1,int y1,int x2,int y2,int k)
{
return f[x2][y2][k]-f[x1-1][y2][k]-f[x2][y1-1][k]+f[x1-1][y1-1][k];
} int cal_g(int x1,int y1,int x2,int y2,int k)
{
return g[x2][y2][k]-g[x1-1][y2][k]-g[x2][y1-1][k]+g[x1-1][y1-1][k];
} void solve1()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) dat[i][j]=read(); for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
for(int k=1;k<=1000;k++)
f[i][j][k]=f[i-1][j][k]+f[i][j-1][k]-f[i-1][j-1][k],
g[i][j][k]=g[i-1][j][k]+g[i][j-1][k]-g[i-1][j-1][k];
f[i][j][dat[i][j]]+=dat[i][j];g[i][j][dat[i][j]]++;
} for(int k=999;k>=1;k--)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
f[i][j][k]+=f[i][j][k+1],g[i][j][k]+=g[i][j][k+1]; while(q--)
{
int x1=read(),y1=read(),x2=read(),y2=read(),h=read(),l=1,r=1000; while(l<=r)
{
int mid=(l+r)>>1;
if(cal_f(x1,y1,x2,y2,mid)>=h) l=mid+1;
else r=mid-1;
} if(!r){puts("Poor QLW");continue;};
cout << cal_g(x1,y1,x2,y2,r)-(cal_f(x1,y1,x2,y2,r)-h)/r << endl; //将这个厚度中多余的书减掉
}
} void Update(int x,int &y,int val,int l,int r)
{
y=++cnt;seg[y]=seg[x]; //不用改变的节点沿用上一次已经完全构造完的
seg[y].sum+=val;seg[y].cnt++;
if(l==r) return; int mid=(l+r)>>1;
if(val<=mid) Update(seg[x].ls,seg[y].ls,val,l,mid);
else Update(seg[x].rs,seg[y].rs,val,mid+1,r);
} int Query(int x,int y,int val,int l,int r)
{
if(l==r) return val/l+(val%l>0); //对整除情况特殊处理 int mid=(l+r)>>1;
int t=seg[seg[y].rs].sum-seg[seg[x].rs].sum;
if(t>=val) return Query(seg[x].rs,seg[y].rs,val,mid+1,r); //厚度范围是(mid+1,r)时足够
else return Query(seg[x].ls,seg[y].ls,val-t,l,mid)+seg[seg[y].rs].cnt-seg[seg[x].rs].cnt; //不够时
} void solve2()
{
for(int i=1;i<=m;i++)
S[i]=read(),Update(root[i-1],root[i],S[i],1,1000),S[i]+=S[i-1]; //以1~i-1的前缀树为模板建树 while(q--)
{
int x1=read(),y1=read(),x2=read(),y2=read(),h=read();
if(S[y2]-S[y1-1]<h) puts("Poor QLW");
else cout << Query(root[y1-1],root[y2],h,1,1000) << endl;
}
} int main()
{
n=read();m=read();q=read();
if(n>1) solve1();
else solve2();
return 0;
}
1、注意数据范围的特点
如每个点数值的范围不大,可以考虑将 大于等于k的个数/总和 这样与数值范围相关的条件加入递推式中
2、如果 一个量是否符合要求 具有单调性,可以对这个量二分答案
3、主席树:
大多数时候是离线的数据结构
需要知道数据的范围。每个节点维护的是1~i个数中处于数据范围[L,R]的数的信息。
也就是说每棵前缀树中维护的是数据范围[1,1000]的区间信息
4、注意x组成y至少要多少个这类问题的书写:
y=y/x+(y%x>0) || y=(y+x-1)/x
[BZOJ 1926] 粟粟的书架的更多相关文章
- bzoj 1926: [Sdoi2010]粟粟的书架 (主席树+二分)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1926 题面; 1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Se ...
- Bzoj 1926: [Sdoi2010]粟粟的书架(二分答案+乱搞+主席树)
1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec Memory Limit: 552 MB Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱 ...
- 【刷题】BZOJ 1926 [Sdoi2010]粟粟的书架
Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Cormen 的文章.粟粟家中有一个 R行C 列的巨型书架,书 ...
- BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案)
BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案) 题意 : 给你一个长为\(R\)宽为\(C\)的矩阵,第\(i\)行\(j\)列的数为\(P_{i,j}\). 有\(m\)次 ...
- bzoj 1926: [Sdoi2010]粟粟的书架
#include<cstdio> #include<iostream> #define N 201 #define M 500008 using namespace std; ...
- BZOJ.1926.[SDOI2010]粟粟的书架(前缀和 主席树 二分)
题目链接 题意: 在给定矩形区域内找出最少的数,满足和>=k.输出数的个数.两种数据范围. 0~50 注意到(真没注意到...)P[i,j]<=1000,我们可以利用前缀和预处理. num ...
- 粟粟的书架(bzoj 1926)
Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co rmen 的文章.粟粟家中有一个 R行C 列的巨型书架, ...
- 【BZOJ-1926】粟粟的书架 二分 + 前缀和 + 主席树
1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec Memory Limit: 552 MBSubmit: 616 Solved: 238[Submit][Statu ...
- [BZOJ1926][SDOI2010]粟粟的书架
BZOJ Luogu Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Cormen 的文章.粟粟家中有一个 R ...
- bzoj1926[Sdoi2010]粟粟的书架 二分 主席树
1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec Memory Limit: 552 MBSubmit: 1064 Solved: 421[Submit][Stat ...
随机推荐
- sshd_conf配置
# $OpenBSD: sshd_config,v 1.80 2008/07/02 02:24:18 djm Exp $ # This is the sshd server system-w ...
- Substrings Sort string 基本操作
You are given nn strings. Each string consists of lowercase English letters. Rearrange (reorder) the ...
- centos7 mysql cluster集群搭建基于docker
1.准备 mn:集群管理服务器用于管理集群的其他节点.我们可以从管理节点创建和配置集群上的新节点.重新启动.删除或备份节点. db2/db3:这是节点间同步和数据复制的过程发生的层. db4/db5: ...
- JS知识总结
1.javascript继承机制 原型继承,访问对象属性时,如果对象内部有就返回,找不到就会从对象原型指向的对象原型中查找,一层一层的查找,直到最顶层的对象原型还找不到,就返回undefined. 2 ...
- iOS 全局变量设置的几种方式~
在iOS开发过程中关于全局变量的几个方法 1. 在APPDelegate中声明并初始化全局变量.AppDelegate可以在整个应用程序中调用,在其他页面中可以使用代码段获取AppDelegate的全 ...
- jQuery通过CSS()方法给指定的元素同时设置多个样式
<!DOCTYPE html> <html> <head> <script src="http://ajax.googleapis.com/ajax ...
- hdu1527取石子游戏---(威佐夫博弈)
感谢 http://www.cnblogs.com/yuyixingkong/p/3362476.html 取石子游戏 Time Limit: 2000/1000 MS (Java/Others) ...
- 【数据结构】bzoj3747Kinoman
Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l< ...
- 【BZOJ4031】【HEOI2015】小Z的房间 [Matrix-Tree][行列式]
小Z的房间 Time Limit: 10 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 你突然有了一个大房子,房子里面有 ...
- 【Codeforces】849D. Rooter's Song
[算法]模拟 [题意]http://codeforces.com/contest/849/problem/D 给定n个点从x轴或y轴的位置p时间t出发,相遇后按对方路径走,问每个数字撞到墙的位置.(还 ...