BZOJ 1135 [POI2009]Lyz (Hall 定理)
神仙题。
乍一看是二分图匹配的裸题。
但是范围特别大。
考虑用\(Hall\)定理来做。
有一个神仙结论:
假设\(a_i\)是i号鞋的人,则只要任意的\([l,r]\)满足\(\sum_{i = l}^r a_i >=(r - l + 1 + d)*k\)就可以。
转换一下式子成为:
\(\sum_{i=l}^r(a_i - k)>=d*k\)
我们发现维护一下最大子序列的值判断一下就行了.
m写成nWA了8发也是没谁了。
/*header*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#define gc getchar()
#define pc putchar
#define int long long
#define mk make_pair
#define fi first
#define se second
using std::min;
using std::max;
using std::swap;
const int maxN = 200000 + 7;
inline int gi() {
int x = 0,f = 1;char c = gc;
while(c < '0' || c > '9') {if(c == '-')f = -1;c = gc;}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = gc;}return x * f;
}
#define lson now << 1
#define rson now << 1 | 1
struct Node {
int lmax , rmax, mafie, sum;
void init() {
lmax = rmax = mafie = sum;
}
}tree[maxN << 2];
int a[maxN];
void updata(int now) {
tree[now].lmax = max(tree[lson].lmax , tree[rson].lmax + tree[lson].sum);
tree[now].rmax = max(tree[rson].rmax , tree[lson].rmax + tree[rson].sum);
tree[now].mafie = max(tree[lson].rmax + tree[rson].lmax , max(tree[lson].mafie , tree[rson].mafie) );
tree[now].sum = tree[lson].sum + tree[rson].sum;
}
int d , k;
void change(int pos,int val,int l, int r, int now) {
if(l == r) {
tree[now].sum += val;
tree[now].init();
return;
}
int mid = (l + r) >> 1;
if(pos <= mid) change(pos,val,l, mid, lson);
else change(pos , val,mid + 1, r,rson);
updata(now);
}
main() {
int n = gi() , m = gi();
k = gi();d = gi();
for(int i = 1;i <= n;++ i) change(i , -k, 1, n, 1);
for(int i = 1;i <= m;++ i) {
int pos = gi() , val = gi();
change(pos , val, 1, n, 1);
tree[1].mafie <= d * k ? puts("TAK") : puts("NIE");
}
return 0;
}