Hall定理(bzoj 1135: [POI2009]Lyz)

Hall定理(二分图重要定理):

对于二分图U, V(|U|<|V|),设M(Ux)为V中可以与Ux中的点相连的点集,如果该二分图存在完美匹配

那么对于任意点集x∈U都有|M(x)|>=|x|


1135: [POI2009]Lyz

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 490   Solved: 227
[ Submit][ Status][ Discuss]

Description

初始时滑冰俱乐部有1到n号的溜冰鞋各k双。已知x号脚的人可以穿x到x+d的溜冰鞋。 有m次操作,每次包含两个数ri,xi代表来了xi个ri号脚的人。xi为负,则代表走了这么多人。 对于每次操作,输出溜冰鞋是否足够。

Input

n m k d ( 1≤n≤200,000 , 1≤m≤500,000 , 1≤k≤10^9 , 0≤d≤n ) ri xi ( 1≤i≤m, 1≤ri≤n-d , |xi|≤10^9 )

Output

对于每个操作,输出一行,TAK表示够 NIE表示不够。

Sample Input

4 4 2 1
1 3
2 3
3 3
2 -1

Sample Output

TAK
TAK
NIE
TAK


这题有解的条件就是对于任意一个人的集合<=它们可以穿的鞋子的数量(只要任意一个人可穿就算)

有100000个人,那么就会有2^100000个集合,枚举肯定不可能

先贪心一下:

每个人可以穿的鞋子是连续的,那么人只要检查连续的子序列就够了,没必要枚举所有集合

因为如果某个非连续子序列不合法,那么把中间没选的人也选上构成的连续子序列显然更不可能合法

这样就只用枚举100000²个集合

但还是超时


回到有解的条件公式+验证最长连续子序列有


相当于求出当前a[i]-k的最大子段和,看是否大于d*k就好

这样问题就变成了带修改的最大子段和


#include<stdio.h>
#include<algorithm>
using namespace std;
#define LL long long
typedef struct
{
	LL sum;
	LL lm, rm, sm;
}Tree;
Tree tre[844444];
void Update(LL l, LL r, LL x, LL a, LL b)
{
	LL m;
	if(l==r)
	{
		tre[x].sum += b;
		tre[x].lm = tre[x].rm = tre[x].sm += b;
		return;
	}
	m = (l+r)/2;
	if(a<=m)
		Update(l, m, x*2, a, b);
	else
		Update(m+1, r, x*2+1, a, b);
	tre[x].sum = tre[x*2].sum+tre[x*2+1].sum;
	tre[x].lm = max(tre[x*2].lm, tre[x*2].sum+tre[x*2+1].lm);
	tre[x].rm = max(tre[x*2+1].rm, tre[x*2].rm+tre[x*2+1].sum);
	tre[x].sm = max(tre[x*2].rm+tre[x*2+1].lm, max(tre[x*2].sm, tre[x*2+1].sm));
}
int main(void)
{
	LL n, m, k, d, i, a, b;
	scanf("%lld%lld%lld%lld", &n, &m, &k, &d);
	for(i=1;i<=n;i++)
		Update(1, n, 1, i, -k);
	while(m--)
	{
		scanf("%lld%lld", &a, &b);
		Update(1, n, 1, a, b);
		if(tre[1].sm<=k*d)
			printf("TAK\n");
		else
			printf("NIE\n");
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值