BZOJ1135: [POI2009]Lyz

1135: [POI2009]Lyz

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 264  Solved: 106
[Submit][Status]

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

HINT

 

Source

题解:

暴力的话是每次构图跑个最大匹配,显然会T。

然后因为只需要判断能否把人全部匹配完了,所以我们有二分图匹配中的hall定理:

Hall定理:
此定理使用于组合问题中,二部图G中的两部分顶点组成的集合分别为X, Y, X={X1, X2, X3,X4,.........,Xm}, Y={y1, y2, y3, y4 ,.........,yn},G中有一组无公共点的边,一端恰好为组成X的点的充分必要条件是:
X中的任意k个点至少与Y中的k个点相邻。(1≤k≤m)
 
那么有解的条件就是任意一个人的集合的人数<=所连接的鞋子数量
可以看出,当人是连续的时候鞋子所连接数量最少,所以我们只需要判断连续的子序列是否满足题意即可。否则既然连续的都满足题意,那么分开之后一定会有更多的鞋子被连进来。

用  表示鞋号为i的人的个数

那么

 

维护t'i的最长连续子序列  ---zky

代码:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 250000
14 #define maxm 500+100
15 #define eps 1e-10
16 #define ll long long
17 #define pa pair<int,int>
18 #define for0(i,n) for(int i=0;i<=(n);i++)
19 #define for1(i,n) for(int i=1;i<=(n);i++)
20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
22 #define mod 1000000007
23 using namespace std;
24 inline int read()
25 {
26     int x=0,f=1;char ch=getchar();
27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
29     return x*f;
30 }
31 struct seg{ll l,r,lx,rx,mx,sum;}t[4*maxn];
32 ll n,m,kk,d;
33 inline void build(int k,int l,int r)
34 {
35     t[k].l=l;t[k].r=r;int mid=(l+r)>>1;
36     t[k].lx=t[k].rx=t[k].mx=-kk;t[k].sum=-(r-l+1)*kk;
37     if(l==r)return;
38     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
39 }
40 inline void pushup(int k)
41 {
42     int l=k<<1,r=k<<1|1;
43     t[k].lx=max(t[l].lx,t[l].sum+t[r].lx);
44     t[k].rx=max(t[r].rx,t[r].sum+t[l].rx);
45     t[k].mx=max(t[l].rx+t[r].lx,max(t[l].mx,t[r].mx));
46     t[k].sum=t[l].sum+t[r].sum;
47 }
48 inline void add(int k,int x,ll y)
49 {
50     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
51     if(l==r){t[k].sum+=y;t[k].mx=t[k].lx=t[k].rx=t[k].sum;return;}
52     if(x<=mid)add(k<<1,x,y);else add(k<<1|1,x,y);
53     pushup(k);
54 }
55 int main()
56 {
57     freopen("input.txt","r",stdin);
58     freopen("output.txt","w",stdout);
59     n=read();m=read();kk=read();d=read();
60     build(1,1,n);
61     while(m--)
62     {
63         int x=read();ll y=read();
64         add(1,x,y);
65         printf("%s\n",t[1].mx<=d*kk?"TAK":"NIE");
66     }
67     return 0;
68 }
View Code

 

posted @ 2014-11-16 10:04  ZYF-ZYF  Views(516)  Comments(0Edit  收藏  举报