【洛谷2468】[SDOI2010] 粟粟的书架(二合一)
大致题意: 问你选取一个矩形区间内至少几个数,才能使它们的和\(\ge H_i\)。
二合一
根据数据范围,比较显然能看出它是一道二合一的题目。
对于第一种情况,\(R,C\le 200\),我们可以用前缀和+二分去做。
而对于另一种情况,\(R=1,C\le500000\),就需要使用主席树 了。
前缀和+二分
先来讲讲第一种情况。
我们可以用\(sum_{i,j,k}\)来表示 \((1,1)\)到\((i,j)\)的矩形区间内\(\ge k\)的数的总和,然后用\(tot_{i,j,k}\)来表示 \((1,1)\)到\((i,j)\)的矩形区间内\(\ge k\)的数的个数。
这样一来,如何二分应该不用多说了吧!
直接二分\(k\)的大小即可。
主席树
显然,对于\(R=1\),我们可以用主席树来维护。
我们可以直接在树上查询,求出最少的和\(\ge H_i\)的数的个数。
这应该是主席树比较经典的操作了。
如果不会,可以参考代码。
代码
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define uint unsigned int
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define abs(x) ((x)<0?-(x):(x))
#define INF 1e9
#define Inc(x,y) ((x+=(y))>=MOD&&(x-=MOD))
#define ten(x) (((x)<<3)+((x)<<1))
#define P 1000
using namespace std;
int n,m;
class FIO
{
private:
#define Fsize 100000
#define tc() (FinNow==FinEnd&&(FinEnd=(FinNow=Fin)+fread(Fin,1,Fsize,stdin),FinNow==FinEnd)?EOF:*FinNow++)
#define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,FoutSize,stdout),Fout[(FoutSize=0)++]=ch))
int f,FoutSize,OutputTop;char ch,Fin[Fsize],*FinNow,*FinEnd,Fout[Fsize],OutputStack[Fsize];
public:
FIO() {FinNow=FinEnd=Fin;}
inline void read(int &x) {x=0,f=1;while(!isdigit(ch=tc())) f=ch^'-'?1:-1;while(x=ten(x)+(ch&15),isdigit(ch=tc()));x*=f;}
inline void read_char(char &x) {while(isspace(x=tc()));}
inline void read_string(string &x) {x="";while(isspace(ch=tc()));while(x+=ch,!isspace(ch=tc())) if(!~ch) return;}
inline void write(int x) {if(!x) return (void)pc('0');if(x<0) pc('-'),x=-x;while(x) OutputStack[++OutputTop]=x%10+48,x/=10;while(OutputTop) pc(OutputStack[OutputTop]),--OutputTop;}
inline void write_char(char x) {pc(x);}
inline void write_string(string x) {register int i,len=x.length();for(i=0;i<len;++i) pc(x[i]);}
inline void end() {fwrite(Fout,1,FoutSize,stdout);}
}F;
class Class_SumSolver//前缀和+二分
{
private:
#define N 200
#define get_val(array,x1,y1,x2,y2,v) (array[x2][y2][v]-array[x1-1][y2][v]-array[x2][y1-1][v]+array[x1-1][y1-1][v])//求出区间内的值
int a[N+5][N+5],sum[N+5][N+5][P+5],tot[N+5][N+5][P+5];
public:
inline void Solve()
{
register int i,j,k,Q,x1,y1,x2,y2,v,l,r,mid;
for(F.read(Q),i=1;i<=n;++i) for(j=1;j<=m;++j)//读入+预处理
{
for(F.read(a[i][j]),k=0;k<=a[i][j];++k) sum[i][j][k]=sum[i-1][j][k]+sum[i][j-1][k]-sum[i-1][j-1][k]+a[i][j],tot[i][j][k]=tot[i-1][j][k]+tot[i][j-1][k]-tot[i-1][j-1][k]+1;
for(;k<=P;++k) sum[i][j][k]=sum[i-1][j][k]+sum[i][j-1][k]-sum[i-1][j-1][k],tot[i][j][k]=tot[i-1][j][k]+tot[i][j-1][k]-tot[i-1][j-1][k];
}
while(Q--)
{
F.read(x1),F.read(y1),F.read(x2),F.read(y2),F.read(v);
if(get_val(sum,x1,y1,x2,y2,0)<v) {F.write_string("Poor QLW\n");continue;}//特判是否无解
for(mid=(l=0)+(r=P+1)+1>>1;l+1<r;mid=l+r+1>>1) get_val(sum,x1,y1,x2,y2,mid)>=v?l=mid:r=mid;//二分
F.write(get_val(tot,x1,y1,x2,y2,l)-(get_val(sum,x1,y1,x2,y2,l)-v)/l),F.write_char('\n');//输出答案
}
}
}SumSolver;
class Class_ChairmanTreeSolver//主席树
{
private:
#define M 500000
#define LogP 10
int a[M+5],sum[M+5];
class Class_ChairmanTree
{
private:
int n,v,tot,Root[M+5];
struct Tree
{
int Sum,Size,Son[2];
}node[P*LogP+5];
inline void Build(int l,int r,int &rt)//建树
{
if(!rt) rt=++tot;if(!(l^r)) return;
register int mid=l+r>>1;
Build(l,mid,node[rt].Son[0]),Build(mid+1,r,node[rt].Son[1]);
}
inline void upt(int l,int r,int &rt,int lst,int val)//修改
{
node[rt=++tot]=node[lst],node[rt].Sum+=val,++node[rt].Size;
if(!(l^r)) return;
register int mid=l+r>>1;
val<=mid?upt(l,mid,node[rt].Son[0],node[lst].Son[0],val):upt(mid+1,r,node[rt].Son[1],node[lst].Son[1],val);
}
inline int qry(int l,int r,int rt1,int rt2,int v)//查询
{
if(!(l^r)) return (v+l-1)/l;
register int mid=l+r>>1,t=node[node[rt2].Son[1]].Sum-node[node[rt1].Son[1]].Sum;
if(t<v) return node[node[rt2].Son[1]].Size-node[node[rt1].Son[1]].Size+qry(l,mid,node[rt1].Son[0],node[rt2].Son[0],v-t);
return qry(mid+1,r,node[rt1].Son[1],node[rt2].Son[1],v);
}
public:
inline void Init(int len) {n=len,Build(1,n,Root[0]);}
inline void Insert(int val) {++v,upt(1,n,Root[v],Root[v-1],val);}
inline int Query(int ql,int qr,int v) {return qry(1,n,Root[ql-1],Root[qr],v);}
}ChairmanTree;
public:
inline void Solve()
{
register int i,Q,x,y,v;
for(ChairmanTree.Init(P),F.read(Q),i=1;i<=m;++i) F.read(a[i]),sum[i]=sum[i-1]+a[i],ChairmanTree.Insert(a[i]);//读入,预处理前缀和,然后将该元素插入主席树
while(Q--)
{
F.read(x),F.read(x),F.read(y),F.read(y),F.read(v);
if(sum[y]-sum[x-1]<v) {F.write_string("Poor QLW\n");continue;}//特判是否无解
F.write(ChairmanTree.Query(x,y,v)),F.write_char('\n');//在主席树上查询
}
}
}ChairmanTreeSolver;
int main()
{
if(F.read(n),F.read(m),n^1) SumSolver.Solve();else ChairmanTreeSolver.Solve();
return F.end(),0;
}
【洛谷2468】[SDOI2010] 粟粟的书架(二合一)的更多相关文章
- 洛谷P2468 [SDOI2010]粟粟的书架
来了来了,随便拽一道题写题解[大雾] 最近发现自己基础奇差于是开始复习之前学过的东西,正好主席树我几乎完全没学会,然后打开洛谷试炼场… 发现了这么一道二合一的题. 这道题其实分成两个部分,前50%是一 ...
- 洛谷P2468 SDOI 2010 粟粟的书架
题意:给你一个矩形书架,每个点是这本书的页数,每次询问(x1,y1)(x2,y2)这个小矩形里最少需要取几本书使得页数和等于Hi. 题解:小数据二位前缀和预处理+二分答案,大数据一行所以用主席树做,感 ...
- 洛谷P2480 [SDOI2010]古代猪文(费马小定理,卢卡斯定理,中国剩余定理,线性筛)
洛谷题目传送门 蒟蒻惊叹于一道小小的数论题竟能涉及这么多知识点!不过,掌握了这些知识点,拿下这道题也并非难事. 题意一行就能写下来: 给定\(N,G\),求\(G^{\sum \limits _{d| ...
- BZOJ1925或洛谷2467 [SDOI2010]地精部落
BZOJ原题链接 洛谷原题链接 先讲下关于波动数列的\(3\)个性质. 性质\(1\):对于数列中的每一对\(i\)和\(i + 1\),若它们不相邻,那么交换这两个数形成的依旧是一个波动数列. 性质 ...
- 洛谷 P2467 [SDOI2010]地精部落
洛谷 我讲的应该没有这个[https://www.luogu.org/blog/user55639/solution-p2467]清楚. 贴个代码算了: #include <bits/stdc+ ...
- 洛谷 P2481 [SDOI2010]代码拍卖会
洛谷 这大概是我真正意义上的第一道黑题吧! 自己想出了一个大概,状态转移方程打错了一点点,最后还是得看题解. 一句话题意:求出有多少个\(n\)位的数,满足各个位置上的数字从左到右不下降,且被\(p\ ...
- BZOJ5291/洛谷P4458/LOJ#2512 [Bjoi2018]链上二次求和 线段树
原文链接http://www.cnblogs.com/zhouzhendong/p/9031130.html 题目传送门 - LOJ#2512 题目传送门 - 洛谷P4458 题目传送门 - BZOJ ...
- 洛谷 P3380 bzoj3196 Tyvj1730 【模板】二逼平衡树(树套树)
[模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在 ...
- 洛谷P4458 /loj#2512.[BJOI2018]链上二次求和(线段树)
题面 传送门(loj) 传送门(洛谷) 题解 我果然是人傻常数大的典型啊-- 题解在这儿 //minamoto #include<bits/stdc++.h> #define R regi ...
- 洛谷-P5357-【模板】AC自动机(二次加强版)
题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但 ...
随机推荐
- css 实现三栏布局的四种方式
三栏布局就是左中右,左右两边固定,中间自适应. 1. 绝对定位 <div class="left">左边</div> <div class=" ...
- EOS多主机多节点环境配置
本文使用了四台同网段的主机,第一台做为eosio创世用户使用,另外三台做为出块者节点使用,最终实现了EOS多主机多节点的配置.最后EOSIO创世用户不再出块,由选举出来的各个节点轮流出块,下面将介绍具 ...
- emmet高级技巧
编写好HTML和CSS代码时,我们也需要修改或添加一些内容,Emmet提供了很多非常独特的工具,可以大大提高编辑体验,下面我们挑选几个常用的功能来介绍. 萨龙龙发现在sublime text中安装的E ...
- myeclipse非正常关闭处理办法
myeclipse正常或非正常关闭后,再次运行,不显示启动时的logo和读条,进入主页面后程序基本就卡死,无法正常运行,解决办法. 方法一:修改工作空间在刚启动Myeclipse的时候会有一个选择工作 ...
- 几种复杂度的斐波那契数列的Java实现
一:斐波那契数列问题的起源 13世纪初期,意大利数论家Leonardo Fibonacci在他的著作Liber Abaci中提出了兔子的繁殖问题: 如果一开始有一对刚出生的兔子,兔子的长大需要一个月, ...
- CentOS6.x之emacs安装配置编译
刚开始学习linux,干学没什么意思,想在linux下写写程序,了解到linux下使用较多的是emacs和vim,在youtobe上分别看了看这两个工具进行开发的视频,个人感觉emacs比较酷一点,所 ...
- 解决WinSCP连接虚拟机
其实虚拟机你也可以将它形象化,认为它就是一台电脑,只是这个电脑在你的内存中,所以,一般电脑所具有的的功能虚拟机一样拥有,它也可以当成一台独立的个体哦. 针对很多使用WinSCP连接不上虚拟机的问题,这 ...
- 《Head First 设计模式》之命令模式——遥控器
命令模式(Command) ——将“请求”封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 要点 将发出请求的对象和执行请求的对象解耦. 被解耦的两者之间通过 ...
- js中函数声明先提升还是变量先提升
根据官方书籍<你不知道的javascript>(上卷)中写道: "函数会首先被提升,然后才是变量". 例子: console.log(foo); function fo ...
- Linux文件的三个时间属性(Atime,Mtime,Ctime)
Linux下,一个文件有三种时间,分别是: 访问时间:atime 修改时间:mtime 状态时间:ctime 访问时间:对文件进行一次读操作,它的访问时间就会改变.例如像:cat.more等操作,但是 ...