LYZ-Ice Skates

題目鏈接:LYZ-Ice Skates


顯然是一個二分圖匹配問題,所以我們可以想到用霍爾定理來做。

但是我們不能暴力枚舉左邊點的所有情況,但是我們其實只需要找到左邊所有情況的最小值即可。我們顯然可以發現最小值一定是一個連續的區間。因爲這樣重疊是最多的。

所以我們等價於找一個區間:(r-l+1+d)*k>=sum(l,r)在極端情況都是滿足的,所以我們維護區間最大子段和即可。


AC代碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10;
int n,m,k,d;
struct node{int ls,rs,s,sum;}t[N<<2],c;
#define mid (l+r>>1)
inline node merge(node a,node b){
	c.sum=a.sum+b.sum;
	c.ls=max(a.ls,a.sum+b.ls),c.rs=max(b.rs,b.sum+a.rs);
	c.s=max(max(a.s,b.s),a.rs+b.ls);
	return c;
}
void change(int p,int l,int r,int x,int v){
	if(l==r){t[p].ls+=v,t[p].rs+=v,t[p].s+=v,t[p].sum+=v; return ;}
	if(x<=mid)	change(p<<1,l,mid,x,v);
	else	change(p<<1|1,mid+1,r,x,v);
	t[p]=merge(t[p<<1],t[p<<1|1]);
}
signed main(){
	cin>>n>>m>>k>>d;
	for(int i=1;i<=n;i++)	change(1,1,n,i,-k);
	for(int i=1,r,x;i<=m;i++){
		scanf("%lld %lld",&r,&x);	change(1,1,n,r,x);
		if(t[1].s>d*k)	puts("NIE");
		else	puts("TAK");
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章