BZOJ 1135 [POI2009]Lyz (Hall 定理)
阿新 • • 發佈:2019-02-10
get math clas put cto har return init 子序列
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; }
BZOJ 1135 [POI2009]Lyz (Hall 定理)