BZOJ1135: [POI2009]Lyz
2017-03-01 13:50
267 查看
题目大意:初始时滑冰俱乐部有1到n号的溜冰鞋各k双。已知x号脚的人可以穿x到x+d的溜冰鞋。 有m次操作,每次包含两个数ri,xi代表来了xi个ri号脚的人。xi为负,则代表走了这么多人。 对于每次操作,输出溜冰鞋是否足够。
首先——
每次二分图匹配显然是爆炸的
所以有这么一个东西——
Hall定理:对于一个二分图,设左边有n个点,右边有m个点,则左边n个点能完全匹配的充要条件是:对于1<=i<=n,左面任意i个点,都至少有i个右面的点与它相连
然后——
我们肯定不能一一枚举所有的情况,这样是2人数的
我们考虑只挑一些有用的情况来算(也就是最差情况),我们可以把所有的人想象成一个1~n的序列,每个位置存人数。假设我们选的不是脚的型号在连续的一段区间的人的话,分两种情况讨论:
1.这些人对应的鞋的可选型号范围是连续的。那么我们不妨再选上中间没有选到的人,这样人数变多了,而范围不会扩大,这样选到的情况一定更劣的。所以我们无需计算最开始选择的那种方案
2.不是连续的。那就更加好办了,我们只需要计算每段连续的部分就行了。这种情况合法当且仅当每段连续的区间都合法。
于是——
综上所述我们只需要判定每个连续的人形成的段是否满足Hall定理即可
设我们选择的是脚在[l,r]区间内的人,a[i]代表型号为i的有多少人。
想满足Hall定理,则对于任意的l,r我们必须满足这个式子:
∑i=lra[i]<=(r−l+1+d)∗k
操作和询问是O(m)的,大约是50W,每次枚举端点+查询+修改是O(n2logn)的,时间复杂度还是接受不了
于是我们把式子换一种形式写出来
∑i=lr(a[i]−k)<=d∗k
d∗k是一个定值,现在相当于询问把每个a[i]−k之后查询最大连续和并检验其是否小于等于d∗k
那么这件事情就可以用线段树来维护了,需要支持单点修改,最开始的时候把所有的a[i]都设为−k就好了
首先——
每次二分图匹配显然是爆炸的
所以有这么一个东西——
Hall定理:对于一个二分图,设左边有n个点,右边有m个点,则左边n个点能完全匹配的充要条件是:对于1<=i<=n,左面任意i个点,都至少有i个右面的点与它相连
然后——
我们肯定不能一一枚举所有的情况,这样是2人数的
我们考虑只挑一些有用的情况来算(也就是最差情况),我们可以把所有的人想象成一个1~n的序列,每个位置存人数。假设我们选的不是脚的型号在连续的一段区间的人的话,分两种情况讨论:
1.这些人对应的鞋的可选型号范围是连续的。那么我们不妨再选上中间没有选到的人,这样人数变多了,而范围不会扩大,这样选到的情况一定更劣的。所以我们无需计算最开始选择的那种方案
2.不是连续的。那就更加好办了,我们只需要计算每段连续的部分就行了。这种情况合法当且仅当每段连续的区间都合法。
于是——
综上所述我们只需要判定每个连续的人形成的段是否满足Hall定理即可
设我们选择的是脚在[l,r]区间内的人,a[i]代表型号为i的有多少人。
想满足Hall定理,则对于任意的l,r我们必须满足这个式子:
∑i=lra[i]<=(r−l+1+d)∗k
操作和询问是O(m)的,大约是50W,每次枚举端点+查询+修改是O(n2logn)的,时间复杂度还是接受不了
于是我们把式子换一种形式写出来
∑i=lr(a[i]−k)<=d∗k
d∗k是一个定值,现在相当于询问把每个a[i]−k之后查询最大连续和并检验其是否小于等于d∗k
那么这件事情就可以用线段树来维护了,需要支持单点修改,最开始的时候把所有的a[i]都设为−k就好了
#include<iostream> #include<cstdio> #define N 200010 using namespace std; long long l[N<<2],r[N<<2],lm[N<<2],rm[N<<2],w[N<<2],sum[N<<2]; long long n,m,k,d; void pup(long long x) { lm[x]=max(lm[x<<1],sum[x<<1]+lm[x<<1|1]); rm[x]=max(rm[x<<1|1],sum[x<<1|1]+rm[x<<1]); sum[x]=sum[x<<1]+sum[x<<1|1]; w[x]=max(w[x<<1],max(w[x<<1|1],rm[x<<1]+lm[x<<1|1])); } void build(long long now,long long ll,long long rr) { l[now]=ll;r[now]=rr; if(ll==rr) {sum[now]=w[now]=-k;return;} long long mid=(ll+rr)>>1; build(now<<1,ll,mid); build(now<<1|1,mid+1,rr); pup(now); } void change(long long now,long long x,long long v) { if(l[now]==r[now]) { w[now]+=v;sum[now]=w[now]; if(w[now]>0) lm[now]=rm[now]=w[now]; else lm[now]=rm[now]=0; return; } long long mid=(l[now]+r[now])>>1; if(x<=mid) change(now<<1,x,v); else change(now<<1|1,x,v); pup(now); } int main() { scanf("%lld%lld%lld%lld",&n,&m,&k,&d); build(1,1,n); long long i,j,x,y; for(i=1;i<=m;i++) { scanf("%lld%lld",&x,&y); change(1,x,y); if(w[1]>k*d) puts("NIE"); else puts("TAK"); } }
相关文章推荐
- BZOJ1135: [POI2009]Lyz
- BZOJ 1135 POI2009 Lyz 线段树+Hall定理
- 【BZOJ】1135: [POI2009]Lyz
- BZOJ 1135 [POI2009]Lyz 线段树
- BZOJ1135: [POI2009]Lyz
- BZOJ1135 [POI2009]Lyz
- bzoj 1135: [POI2009]Lyz 线段树+Hall定理
- 【BZOJ1135】[POI2009]Lyz 线段树
- 【BZOJ1135】【POI2009】Lyz
- Hall定理(bzoj 1135: [POI2009]Lyz)
- BZOJ[1135][POI2009]Lyz 线段树
- BZOJ1135: [POI2009]Lyz
- 【BZOJ】【P1135】【POI2009】【Lyz】【题解】【线段树+Hall定理】
- 1135: [POI2009]Lyz
- BZOJ 1135: [POI2009]Lyz Hall定理 + 线段树
- 1135: [POI2009]Lyz (线段树)
- BZOJ 1135:[POI2009]Lyz 线段树 + HALL定理
- BZOJ 1115: [POI2009]石子游戏Kam 阶梯尼姆游戏
- BZOJ 1115 [POI2009]石子游戏Kam
- bzoj 1137: [POI2009]Wsp 岛屿 (半平面交)