1. 程式人生 > >[POI2009]Lyz

[POI2009]Lyz

輸出 -o update gist 怎麽 -i times scrip 多人

Description

初始時滑冰俱樂部有1到n號的溜冰鞋各k雙。已知x號腳的人可以穿x到x+d的溜冰鞋。 有m次操作,每次包含兩個數ri,xi代表來了xi個ri號腳的人。xi為負,則代表走了這麽多人。 對於每次操作,輸出溜冰鞋是否足夠。

Input

n m k d ( 1≤n≤200,000 , 1≤m≤500,000 , 1≤k≤10^9 , 0≤d≤n ) ri xi ( 1≤i≤m, 1≤ri≤n-d , |xi|≤10^9 )

Output

對於每個操作,輸出一行,TAK表示夠 NIE表示不夠。

Sample Input

4 4 2 1
1 3
2 3
3 3
2 -1

Sample Output

TAK
TAK

NIE
TAK

Solution

終於從網絡流中解放出來了。

這題怎麽說呢,還是和二分圖有點關系。根據霍爾定理,我們可以得出如果在某一個時刻不符合要求的話,那麽對於一個l,r,一定有\((r-l+1+d)*k<\sum_{l\le i \le r}a_i\)隨便移項就可以得出\(\sum_{l\le i \le r}a_i-(r-l+1)\times k>d*k\)然後在建樹的時候把所有點-k就可以用線段樹維護了。

所以說這題叫動態最大子段和??

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdlib> #include <cmath> #include <string> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #include <set> #include <map> #define re register #define MAXN 200005 #define ls (rt<<1) #define rs (rt<<1|1)
#define mid (l+r>>1) using namespace std; typedef long long ll; typedef unsigned long long ull; #define ms(arr) memset(arr, 0, sizeof(arr)) #define int ll const int inf = 0x3f3f3f3f; int maxl[MAXN<<2],maxr[MAXN<<2],sum[MAXN<<2],maxx[MAXN<<2]; int n,m,K,d; inline void pushup(int rt) { sum[rt]=sum[ls]+sum[rs]; maxl[rt]=max(maxl[ls],sum[ls]+maxl[rs]); maxr[rt]=max(maxr[rs],sum[rs]+maxr[ls]); maxx[rt]=max(maxx[ls],max(maxx[rs],maxl[rs]+maxr[ls])); } inline void build(int l,int r,int rt) { if(l==r){ maxx[rt]=-K;sum[rt]=-K; return; } build(l,mid,ls);build(mid+1,r,rs); pushup(rt); } inline void update(int x,int y,int l,int r,int rt) { if(l==r) { maxx[rt]+=y;sum[rt]+=y; maxl[rt]=maxr[rt]=max(sum[rt],0ll); return; } if(mid>=x) update(x,y,l,mid,ls); else update(x,y,mid+1,r,rs); pushup(rt); } inline int read() { int x=0,c=1; char ch=' '; while((ch>'9'||ch<'0')&&ch!='-')ch=getchar(); while(ch=='-') c*=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar(); return x*c; } main() { n=read();m=read();K=read();d=read(); build(1,n,1); for(re int i=1;i<=m;i++){ int x=read(),y=read(); update(x,y,1,n,1); if(maxx[1]<=K*d) printf("TAK\n"); else printf("NIE\n"); } return 0; }

[POI2009]Lyz