【BZOJ】1135: [POI2009]Lyz
题意
有\(1\)到\(n(1 \le n \le 200000)\)号的溜冰鞋各\(k(1 \le k \le 10^9)\)双。已知\(x\)号脚的人可以穿\(x\)到\(x+d\)的溜冰鞋。
有\(m(1 \le m \le 500000)\)次操作,每次来了\(x_i\)个\(r_i\)号脚的人。\(x_i\)为负,则代表走了这么多人。对于每次操作,输出溜冰鞋是否足够。
分析
容易发现是二分图模型,然而数据太大。
题解
根据Hall定理:如果存在\(X\)的完备匹配,则\(X\)中任意\(k\)个点都至少与\(Y\)中的\(k\)个点相邻。
所以我们只需要在任意一些人使得满足这个条件那么就行了。
然后来了个神结论:
假设\(a_i\)是\(i\)号鞋的人,则只要任意的\([l, r]\)满足\(\sum_{i=l}^{r} a_i \ge (r-l+1+d) * k\),即\(\sum_{i=l}^{r} (a_i-k) \ge d * k\)则可行。
并不知道这个结论怎么来的...
所以用线段树维护一下最大子序列的值即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int getint() {
int x=0, f=1, c=getchar();
for(; c<48||c>57; f=c=='-'?-1:f, c=getchar());
for(; c>47&&c<58; x=x*10+c-48, c=getchar());
return x*f;
}
struct T {
ll mx, mxl, mxr, s;
void init() {
mx=mxl=mxr=s;
}
}t[1000005];
int n, m, k, d;
void up(int x) {
int l=x<<1, r=x<<1|1;
t[x].s=t[l].s+t[r].s;
t[x].mxl=max(t[l].mxl, t[l].s+t[r].mxl);
t[x].mxr=max(t[r].mxr, t[r].s+t[l].mxr);
t[x].mx=max(t[l].mxr+t[r].mxl, max(t[l].mx, t[r].mx));
}
void upd(int p, int g, int l=1, int r=n, int x=1) {
if(l==r) {
t[x].s+=g;
t[x].init();
return;
}
int mid=(l+r)>>1;
if(p<=mid) {
upd(p, g, l, mid, x<<1);
}
else {
upd(p, g, mid+1, r, x<<1|1);
}
up(x);
}
int main() {
n=getint(), m=getint(), k=getint(), d=getint();
for(int i=1; i<=n; ++i) {
upd(i, -k);
}
for(ll te=(ll)d*k; m; --m) {
int r=getint(), x=getint();
upd(r, x);
puts(t[1].mx<=te?"TAK":"NIE");
}
return 0;
}
博客地址:www.cnblogs.com/iwtwiioi 本文为博主原创文章,未经博主允许不得转载。一经发现,必将追究法律责任。