【BZOJ】【P1135】【POI2009】【Lyz】【题解】【线段树+Hall定理】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1135

把鞋子和人抽象成二分图

Hall定理:
此定理使用于组合问题中, 二部图G中的两部分顶点组成的集合分别为X, Y, X={X1, X2, X3,X4, .........,Xm}, Y={y1, y2, y3, y4 , .........,yn},G中有一组无公共点的边,一端恰好为组成X的点的充分必要条件是:
X中的任意k个点至少与Y中的k个点相邻。(1≤k≤m)
那么有解的条件就是任意一个人的集合的人数<=所连接的鞋子数量,对于序列来说连续子序列就够了(我不知道为什么……)

用  表示鞋号为i的人的个数

那么



维护t'i的最长连续子序列

Code:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=2e5+5;
typedef long long LL;
struct seg{
	struct node{
		LL ls,rs,ss,sum;
		node(){ls=rs=ss=sum=0;}
	}t[maxn<<2];
	#define lson i<<1,l,mid
	#define rson i<<1|1,mid+1,r
	#define L i<<1
	#define R i<<1|1
	void Add(int i,int l,int r,int ps,LL d){
		if(l==r){t[i].ls+=d;t[i].rs+=d;t[i].ss+=d;t[i].sum+=d;return;}
		int mid=(l+r)>>1;
		if(ps<=mid)Add(lson,ps,d);else Add(rson,ps,d);
		t[i].ls=max(t[L].ls,t[L].sum+t[R].ls);
		t[i].rs=max(t[R].rs,t[R].sum+t[L].rs);
		t[i].ss=max(t[L].ss,t[R].ss);
		t[i].ss=max(t[i].ss,t[L].rs+t[R].ls);
		t[i].sum=t[L].sum+t[R].sum;
	}	
}T;
int n,m,k,d;
int main(){
	scanf("%d%d%d%d",&n,&m,&k,&d);
	for(int i=1;i<=n;i++)T.Add(1,1,n,i,-k);
	while(m--){
		int x,r;scanf("%d%d",&r,&x);
		T.Add(1,1,n,r,x);
		puts(T.t[1].ss<=(LL)d*k?"TAK":"NIE");
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值