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的更多相关文章

  1. 【BZOJ 2138】stone

    Problem Description 话说 \(Nan\) 在海边等人,预计还要等上 \(M\) 分钟.为了打发时间,他玩起了石子. \(Nan\) 搬来了 \(N\) 堆石子,编号为 \(1\) ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. Hall 定理

    Hall 定理 是匈牙利算法的基础 大意是说,对于一个二分图 左边的集合记为X,右边的集合记为Y 存在完美匹配,(即匹配数目=min(|X|,|Y|))的充分必要条件是 对于任意一个X的子集,设大小为 ...

  4. BZOJ.2000.[HNOI2010]stone取石头游戏(博弈)

    BZOJ 洛谷 低估这道神题了_(:з」∠)_ MilkyWay好狠啊(小声) \(Description\) 有一些数字,被分成若干双端队列(从两边都可以取)和最多两个栈(只能从某一边一个一个取)的 ...

  5. BZOJ 1001 狼抓兔子 (网络流最小割/平面图的对偶图的最短路)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 算法讨论: 1.可以用最大流做,最大流等于最小割. 2.可以把这个图转化其对偶图,然 ...

  6. POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)

    POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流) Description Yo ...

  7. 【BZOJ2138】stone(线段树,Hall定理)

    [BZOJ2138]stone(线段树,Hall定理) 题面 BZOJ 题解 考虑一个暴力. 我们对于每堆石子和每个询问,显然是匹配的操作. 所以可以把石子拆成\(a_i\)个,询问点拆成\(K_i\ ...

  8. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  9. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

随机推荐

  1. win10 打开sql server配置管理器

    win10 安装 sql server之后无法在开始菜单找到“sql server 配置管理器(SQL server configuration manager 1)在开始菜单中,无法找到 配置管理器 ...

  2. js url 参数 转换成 json 对象数据

    some=params&over=here => {"some":"params","over":"here&quo ...

  3. EF 多对多循环引用序列化失败 解决办法

    错误:Self referencing loop detected with type 'System.Data.Entity.DynamicProxies.tbldph_901D48A194FB31 ...

  4. python numpy 数组中元素大于等于0的元素

    >>> import numpy as np >>> a = np.random.randint(-5, 5, (5, 5)) >>> a arr ...

  5. Exp6 信息搜集与漏洞扫描 20164323段钊阳

    20164323 Exp6 信息搜集与漏洞扫描 回答问题 1.哪些组织负责DNS,IP的管理. 全球根服务器均由美国政府授权的ICANN统一管理,负责全球的域名根服务器.DNS和IP地址管理.全球一共 ...

  6. 二叉堆的实现(数组)——c++

    二叉堆的介绍 二叉堆是完全二元树或者是近似完全二元树,按照数据的排列方式可以分为两种:最大堆和最小堆.最大堆:父结点的键值总是大于或等于任何一个子节点的键值:最小堆:父结点的键值总是小于或等于任何一个 ...

  7. Bonjour Operations

    https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/NetServices/Articles/NetServi ...

  8. 话谈C#第一天

    今天是第一次接触C#,由于长时间的做Java开发,突然转到C#非常的不自然,但是也有了一些收获,给大家分享一下 using System; using System.Collections.Gener ...

  9. Android启动过程介绍

    开机过程大致可以分为以下三个阶段 OS级别 由bootloader载入linux kernel后,kernel开始初始化, 并载入built-in的驱动程序.Kernel完成开机后,载入init pr ...

  10. 【hdu4609】 3-idiots FFT

    题外话:好久没写blog了啊-- 题目传送门 题目大意:给你m条长度为ai的线段,求在其中任选三条出来,能构成三角形的概率.即求在这n条线段中找出三条线段所能拼出的三角形数量除以$\binom{m}{ ...