Description
滑冰俱乐部初始有 (1..n) 号码溜冰鞋各 (k) 双,已知 (x) 号脚的人可以穿 (x o x + d) 号码的鞋子。现在有 m 次操作,每次两个数 (r)、(x),表示 (r) 号脚的人来了 (x) 个,(x) 为负表示离开。对于每次操作,输出溜冰鞋是否足够。
题面保证 (rle n-d)
数据范围:(n,x,m≤5 imes10^5,k≤10^9)
Solution
在已经知道定理的情况下没有切掉这题,真是该退役了
定理
一个二分图有完备匹配的最大条件,是左部点的每个子集向右部点连出来的边中,涉及到的右部点的个数大于等于该子集大小
证明?好像可以感性理解……(因为不太会证,导致做不了题)
然后跟这题相关的是,用上上面的那个定理,则有:
[sumlimits_{i=l}^r x_i le (r-l+1+d) imes k
]
对于任意 (l,r) 都成立,那么所有人的有鞋穿
所以我们拆式子
[sum_{i=l}^r (x_i-k)le d imes k
]
对于任意的 (l,r) 都成立
所以维护区间最大子段和,判定是不是满足上面的条件就好了
如果不保证 (rle n-d) 呢?(昨天讲课的时候讲了但是自己忘记了,感谢 (@i207M)
分成两部分维护
对于 (rle n-d) 的照样维护
对于那部分不满足这个性质的
[sum_{i=l} ^r x_i-k imes(n-l+1)>0
]
[sum_{i=l} ^r x_i+k imes l >k imes (n+1)
]
区间左端点乘常数最大值
但是,我们发现这里的最大值一定满足右端点为 (n)
所以维护后缀和,如果面对修改是一个前缀修改
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k=='-') f=-1;
while(isdigit(k)) res=res*10+k-'0',k=getchar();
return res*f;
}
const int N=5e5+10;
struct node{
int l,r,mx,lmx,rmx,sum;
#define mx(p) t[p].mx
#define l(p) t[p].l
#define r(p) t[p].r
#define lmx(p) t[p].lmx
#define rmx(p) t[p].rmx
#define sum(p) t[p].sum
inline void co(int x)
{
mx+=x; lmx+=x; rmx+=x; sum+=x;
return ;
}
}t[N<<2];
int n,m,k,d;
inline void push_up(int p)
{
lmx(p)=max(lmx(p<<1),sum(p<<1)+lmx(p<<1|1));
rmx(p)=max(rmx(p<<1|1),sum(p<<1|1)+rmx(p<<1));
mx(p)=max(mx(p<<1),mx(p<<1|1));
mx(p)=max(lmx(p<<1|1)+rmx(p<<1),mx(p));
sum(p)=sum(p<<1)+sum(p<<1|1);
mx(p)=max(mx(p),sum(p));
return ;
}
inline void build(int p,int l,int r)
{
l(p)=l; r(p)=r; if(l==r) return t[p].co(-k);
int mid=(l+r)>>1;
build(p<<1,l,mid); build(p<<1|1,mid+1,r);
return push_up(p);
}
inline void update(int p,int pos,int x)
{
if(l(p)==pos&&r(p)==pos) return t[p].co(x),void();
int mid=(l(p)+r(p))>>1;
if(pos<=mid) update(p<<1,pos,x);
else update(p<<1|1,pos,x);
return push_up(p);
}
signed main()
{
n=read(); m=read(); k=read(); d=read(); build(1,1,n);
while(m--)
{
int sz=read(),num=read();
update(1,sz,num);
puts(mx(1)<=d*k?"TAK":"NIE");
}
return 0;
}
}
signed main(){return yspm::main();}