BZOJ 1135 [POI2009]Lyz (Hall 定理)

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;
}

猜你喜欢

转载自www.cnblogs.com/gzygzy/p/10360179.html