bzoj 2138: stone
Description
话说Nan在海边等人,预计还要等上M分钟。为了打发时间,他玩起了石子。Nan搬来了N堆石子,编号为1到N,每堆
包含Ai颗石子。每1分钟,Nan会在编号在[Li,Ri]之间的石堆中挑出任意Ki颗扔向大海(好疼的玩法),如果[Li,R
i]剩下石子不够Ki颗,则取尽量地多。为了保留扔石子的新鲜感,Nan保证任意两个区间[Li,Ri]和[Lj,Rj],不会
存在Li<=Lj&Rj<=Ri的情况,即任意两段区间不存在包含关系。可是,如果选择不当,可能无法扔出最多的石子,
这时NN就会不高兴了。所以他希望制定一个计划,他告诉你他m分钟打算扔的区间[Li,Ri]以及Ki。现在他想你告诉
他,在满足前i-1分钟都取到你回答的颗数的情况下,第i分钟最多能取多少个石子。
Solution
如果把 \(m\) 个 \(K_i\) 和 \(n\) 堆石子 \(A_i\) 分别拆点 , 那么实际上就是跑一个完美匹配
假设我们钦定了这一分钟所选择的石子个数 , 判断是否合法就是判断是否存在完美匹配了
判断是否存在完美匹配一般用到 \(Hall\) 定理 , 但是问题是需要枚举 \(K_i\) 集合的所有子集
由于这个题目有很好的性质:右端点单调时,左端点也单调
那么有结论: 只需要对于所有的区间 \([l,r]\,\,l,r∈[1,m]\) 满足 \(Hall\) 定理就行了
证明分两种情况,假设有不相邻 \(i,j\) 构成子集:
1.\(i,j\) 所对应的区间不相交,那么 \(i,j\) 分别满足 \(Hall\) 定理就可以了
2.\(i,j\) 有交,那么 \([i+1,j-1]\) 一定都是被 \([L[i],R[j]]\) 包含的 , 所以实际上只需要关心中间连续的一段是否满足 \(Hall\) 定理和整个区间 \([i,j]\) 是否满足 \(Hall\) 定理就可以了
设每个时间选的石子数量为 \(B_i\) ,剩下的就是要时刻满足:
\(\sum_{i=l}^{r}B_i<=\sum_{i=L[l]}^{R[r]}A_i\)
用前缀和表示:
\(SB[r]-SB[l-1]<=SA[R[r]]-SA[L[l]-1]\)
\(SB[R]-SA[R[r]]<=SB[l-1]-SA[L[l]-1]\)
设 \(C[i]=SB[i]-SA[R[i]],D[i]=SB[i-1]-SA[L[i]-1]\)
那么就是对于所有的 \(l<=r\) 有 \(D[l]>=C[r]\)
每一个时刻能取的上界就是 \(min(D[l])-max(C[r])\)
用线段树维护一下即可,时间复杂度 \(O(M*log)\)
#include<bits/stdc++.h>
#define ls (o<<1)
#define rs (o<<1|1)
#define sqr(x) ((x)*(x))
using namespace std;
template<class T>void gi(T &x){
int f;char c;
for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
}
const int N=4e4+10;
int n,a[N],b[N],id[N],m,p[N],A[N];
struct data{int l,r,id;}q[N];
inline bool operator <(const data &p,const data &q){return p.r<q.r;}
struct seg{
int op,tr[N*4],a[N],la[N*4];
inline int Max(int x,int y){return op?max(x,y):min(x,y);}
inline void build(int l,int r,int o){
if(l==r){tr[o]=a[l];return ;}
int mid=(l+r)>>1;
build(l,mid,ls);build(mid+1,r,rs);
tr[o]=Max(tr[ls],tr[rs]);
}
inline void init(int o){op=o;build(1,m,1);}
inline void pushdown(int o){
if(!la[o])return ;
tr[ls]+=la[o];tr[rs]+=la[o];la[ls]+=la[o];la[rs]+=la[o];la[o]=0;
}
inline int qry(int l,int r,int o,int sa,int se){
if(sa<=l && r<=se)return tr[o];
int mid=(l+r)>>1;pushdown(o);
if(se<=mid)return qry(l,mid,ls,sa,se);
if(sa>mid)return qry(mid+1,r,rs,sa,se);
return Max(qry(l,mid,ls,sa,mid),qry(mid+1,r,rs,mid+1,se));
}
inline void ins(int l,int r,int o,int sa,int se,int t){
if(sa<=l && r<=se){tr[o]+=t;la[o]+=t;return ;}
int mid=(l+r)>>1;pushdown(o);
if(se<=mid)ins(l,mid,ls,sa,se,t);
else if(sa>mid)ins(mid+1,r,rs,sa,se,t);
else ins(l,mid,ls,sa,mid,t),ins(mid+1,r,rs,mid+1,se,t);
tr[o]=Max(tr[ls],tr[rs]);
}
}C,D;
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
int x,y,z,P;
cin>>n>>x>>y>>z>>P;
for(int i=1;i<=n;i++)a[i]=(1ll*sqr(i-x)+sqr(i-y)+sqr(i-z))%P;
cin>>m;
if(!m)return 0;
cin>>b[1]>>b[2]>>x>>y>>z>>P;
for(int i=3;i<=m;i++)b[i]=(x*b[i-1]+y*b[i-2]+z)%P;
for(int i=1;i<=m;i++)gi(q[i].l),gi(q[i].r),q[i].id=i;
sort(q+1,q+m+1);n=0;
for(int i=1,j=1;i<=m;i++){
for(j=max(j,q[i].l);j<=q[i].r;j++)A[id[j]=++n]=a[j];
q[i].l=id[q[i].l];q[i].r=id[q[i].r];p[q[i].id]=i;
}
for(int i=1;i<=n;i++)A[i]+=A[i-1];
for(int i=1;i<=m;i++)C.a[i]=-A[q[i].r],D.a[i]=-A[q[i].l-1];
C.init(1);D.init(0);
for(int i=1;i<=m;i++){
x=p[i];
int rm=C.qry(1,m,1,p[i],m),lm=D.qry(1,m,1,1,p[i]);
int res=min(b[i],lm-rm);
printf("%d\n",res);
C.ins(1,m,1,p[i],m,res);
if(p[i]<m)D.ins(1,m,1,p[i]+1,m,res);
}
return 0;
}
bzoj 2138: stone的更多相关文章
- 【BZOJ 2138】stone
Problem Description 话说 \(Nan\) 在海边等人,预计还要等上 \(M\) 分钟.为了打发时间,他玩起了石子. \(Nan\) 搬来了 \(N\) 堆石子,编号为 \(1\) ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- Hall 定理
Hall 定理 是匈牙利算法的基础 大意是说,对于一个二分图 左边的集合记为X,右边的集合记为Y 存在完美匹配,(即匹配数目=min(|X|,|Y|))的充分必要条件是 对于任意一个X的子集,设大小为 ...
- BZOJ.2000.[HNOI2010]stone取石头游戏(博弈)
BZOJ 洛谷 低估这道神题了_(:з」∠)_ MilkyWay好狠啊(小声) \(Description\) 有一些数字,被分成若干双端队列(从两边都可以取)和最多两个栈(只能从某一边一个一个取)的 ...
- BZOJ 1001 狼抓兔子 (网络流最小割/平面图的对偶图的最短路)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 算法讨论: 1.可以用最大流做,最大流等于最小割. 2.可以把这个图转化其对偶图,然 ...
- POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)
POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流) Description Yo ...
- 【BZOJ2138】stone(线段树,Hall定理)
[BZOJ2138]stone(线段树,Hall定理) 题面 BZOJ 题解 考虑一个暴力. 我们对于每堆石子和每个询问,显然是匹配的操作. 所以可以把石子拆成\(a_i\)个,询问点拆成\(K_i\ ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
随机推荐
- Nodejs-- web服务器
第一篇关于nodejs的东西,代码在此作为备份. 该代码目前未完成,是一个阻塞式的代码. 1.index.js ar server=require('./server'); var route=req ...
- AbpZero之企业微信---登录(拓展第三方auth授权登录)---第一步:查看AbpZero的auth第三方登录的底层机制
在AbpZero框架中,auth登录接口位于Web.Core库下的Controllers文件夹的TokenAuthController.cs的ExternalAuthenticate方法 Extern ...
- 在Windows安装Reids 详解
今天安装了redis,记录点经验 因为Redis项目没有正式支持Windows. 但Microsoft开发和维护一个针对Windows 64版的redis. 下载地址在微软的GitHub上,地址:ht ...
- C# 对象引擎,以路径形式访问对象属性(data.Product[1].Name)
对象引擎,以路径形式访问对象属性,例data.Product[1].Name. 在做excel模板引擎的时候,为了能方便的调用对象属性,找了一些模板引擎,不是太大就是不太适用于excel, 因为exc ...
- pageadmin CMS网站制作教程:
pageadmin CMS网站建设教程:模板中如何实现信息数据共享 很多时候信息数据需要共享,一个最常用的应用场景就是手机版(独立手机,非响应式)本共享pc版本数据,下面以这个场景为例讲解. 假设手机 ...
- Mysql数据库二:表的增删改查
----建表CREATE TABLE emp( id int PRIMARY key auto_increment, name char(10) , birthday DATE , salary FL ...
- 二叉堆的实现(数组)——c++
二叉堆的介绍 二叉堆是完全二元树或者是近似完全二元树,按照数据的排列方式可以分为两种:最大堆和最小堆.最大堆:父结点的键值总是大于或等于任何一个子节点的键值:最小堆:父结点的键值总是小于或等于任何一个 ...
- 内核漏洞学习—熟悉HEVD
一直以来内核漏洞安全给很多人的印象就是:难,枯燥.但是内核安全是否掌握是衡量一个系统安全工程师水平的标准之一,也是安全从业人员都应该掌握的基本功.本文通过详细的实例带领读者走进内核安全的大门.难度系数 ...
- 二:MyBatis学习总结(二)——使用MyBatis对表执行CRUD操作
上一篇博文MyBatis学习总结(一)——MyBatis快速入门中我们讲了如何使用Mybatis查询users表中的数据,算是对MyBatis有一个初步的入门了,今天讲解一下如何使用MyBatis对u ...
- 使用win10自带邮件应用发送文件
之前的电脑装过邮件客户端,想发送文件给别人时,只需要“右键文件——发送到邮件”,就能把文件作为附件发送给对方.新电脑win10系统自带邮件客户端,所以就想直接用.但是右键发送到邮件没有关联上,用不了. ...