bzoj 1135 [POI2009]Lyz 线段树+hall定理
1135: [POI2009]Lyz
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 573 Solved: 280
[Submit][Status][Discuss]
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
1 3
2 3
3 3
2 -1
Sample Output
TAK
TAK
NIE
TAK
TAK
NIE
TAK
题解:
可以转换一下模型,每个人都有鞋穿不就等价于二分图存在完美匹配。
根据hall定理,对于一个二分图,设左边有n个点,右边有m个点,则左边n个点
能完全匹配的充要条件是:对于1<=i<=n,左面任意i个点,都至少有i个右面的点与它相连
hall定理很容易理解,然后后面我就直接贴别人的了。
1 #include<cstring> 2 #include<cmath> 3 #include<cstdio> 4 #include<algorithm> 5 #include<iostream> 6 7 #define ll long long 8 #define N 200007 9 10 #define Wb putchar(' ') 11 #define We putchar('\n') 12 #define rg register int 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 18 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 inline void write(int x) 22 { 23 if(x<0) putchar('-'),x=-x; 24 if (x==0) putchar(48); 25 int num=0;char c[15]; 26 while(x) c[++num]=(x%10)+48,x/=10; 27 while(num) putchar(c[num--]); 28 } 29 30 int n,m,k,d; 31 struct seg 32 { 33 struct node 34 { 35 ll ls,rs,ss,sum; 36 node(){ls=rs=ss=sum=0;} 37 }t[N<<2]; 38 #define lson i<<1,l,mid 39 #define rson i<<1|1,mid+1,r 40 #define L i<<1 41 #define R i<<1|1 42 void update(int i) 43 { 44 t[i].ls=max(t[L].ls,t[L].sum+t[R].ls); 45 t[i].rs=max(t[R].rs,t[R].sum+t[L].rs); 46 t[i].ss=max(t[L].ss,t[R].ss); 47 t[i].ss=max(t[i].ss,t[L].rs+t[R].ls); 48 t[i].sum=t[L].sum+t[R].sum; 49 } 50 void Add(int i,int l,int r,int ps,ll d) 51 { 52 if(l==r){t[i].ls+=d;t[i].rs+=d;t[i].ss+=d;t[i].sum+=d;return;} 53 int mid=(l+r)>>1; 54 if(ps<=mid)Add(lson,ps,d); 55 else Add(rson,ps,d); 56 update(i); 57 } 58 #undef lson 59 #undef rson 60 #undef L 61 #undef R 62 }T; 63 64 int main() 65 { 66 n=read(),m=read(),k=read(),d=read(); 67 for(int i=1;i<=n;i++)T.Add(1,1,n,i,-k); 68 while(m--) 69 { 70 int r=read(),x=read(); 71 T.Add(1,1,n,r,x); 72 puts(T.t[1].ss<=(ll)d*k?"TAK":"NIE"); 73 } 74 }