题解 bzoj1135: [POI2009]Lyz (线段树+霍尔定理)
Posted ning-mew
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 bzoj1135: [POI2009]Lyz (线段树+霍尔定理)相关的知识,希望对你有一定的参考价值。
Solution
- 二分图是显然的,用二分图匹配显然在这个范围会炸的很惨,我们考虑用霍尔定理。
- 我们任意选取穿(l,r)的号码鞋子的人,那么这些人可以穿的鞋子的范围是(l,r+d),这个时候我们可以根据霍尔定理得出满足人人有鞋子穿的时候的式子是
令(sum[i])表示穿(i)号鞋子的人数
[Sigma^r_{i=l} sum[i] leq (r-l+1+d)*k]
我们把这个式子整理下:
[Sigma^r_{i=l} (sum[i]-k) leq d*k] - 我们会发现右边是一个常量,那么这个式子就等价与左边的最大值小于等右边即满足,否则不满足
- 所以我们就只需要找出(1 ightarrow n)中最大连续子序列。
New Knowledge
- 最大连续子序列用线段树来维护,重难点在(update)
- 向上更新
void update(int now,int nl,int nr){
node[now].sum=node[ls(now)].sum+node[rs(now)].sum;
node[now].lmax=max(node[ls(now)].lmax,node[ls(now)].sum+node[rs(now)].lmax);
node[now].rmax=max(node[rs(now)].rmax,node[ls(now)].rmax+node[rs(now)].sum);
node[now].maxx=max( node[ls(now)].rmax+node[rs(now)].lmax ,
max( node[ls(now)].maxx , node[rs(now)].maxx) );return;
}
Code
//It is coded by ning_mew on 7.18
#include<bits/stdc++.h>
#define ls(x) (x*2)
#define rs(x) (x*2+1)
#define LL long long
using namespace std;
const int maxn=2e5+7;
int n,m,d;LL k;
struct Node{LL lmax,rmax,maxx,sum;}node[maxn*4];
void update(int now,int nl,int nr){
node[now].sum=node[ls(now)].sum+node[rs(now)].sum;
node[now].lmax=max(node[ls(now)].lmax,node[ls(now)].sum+node[rs(now)].lmax);
node[now].rmax=max(node[rs(now)].rmax,node[ls(now)].rmax+node[rs(now)].sum);
node[now].maxx=max( node[ls(now)].rmax+node[rs(now)].lmax , max( node[ls(now)].maxx , node[rs(now)].maxx) );return;
}
void build(int now,int nl,int nr){
if(nl==nr){node[now].sum=node[now].maxx=node[now].lmax=node[now].rmax=-k;return;}
int mid=(nl+nr)/2;
build(ls(now),nl,mid);build(rs(now),mid+1,nr);
update(now,nl,nr);
}
void add(int now,int nl,int nr,int pl,LL ad){
if(nl==nr&&nr==pl){
LL box=node[now].sum+ad; node[now].sum=box;node[now].maxx=box;node[now].lmax=box;node[now].rmax=box; return;
} if(nr<pl||pl<nl)return;
int mid=(nl+nr)/2;
add(ls(now),nl,mid,pl,ad);add(rs(now),mid+1,nr,pl,ad);
update(now,nl,nr);
}
int main(){
scanf("%d%d%lld%d",&n,&m,&k,&d);
build(1,1,n);
for(int i=1;i<=m;i++){
int r;LL x;scanf("%d%lld",&r,&x);
add(1,1,n,r,x);//cout<<node[1].maxx<<endl;
if(node[1].maxx>d*k)printf("NIE
");else printf("TAK
");
}return 0;
}
博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/Ning-Mew/,否则你会场场比赛暴0!!!
以上是关于题解 bzoj1135: [POI2009]Lyz (线段树+霍尔定理)的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1135 [POI2009]Lyz 线段树+hall定理