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

来源:互联网 发布:高斯白噪声协方差矩阵 编辑:程序博客网 时间:2024/05/16 10:41

传送门: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|1void 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
原创粉丝点击