8
8
2015
0

【二分+差分】NOIP2012 T5借教室

前缀&差分大法好。

SHC太大了:线段树维护区间最小值和Lazy_Tag……

本蒟蒻:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

因为是最小的i,所以答案具有可二分性。

所以考虑二分订单,并模拟出剩余的教室数组

因为是区间加减,所以可以用差分维护,最后前缀和还原。

于是有了个常数巨大的姿势。

又发现差分上操作会有大量重复。

用个栈压着。

复杂度$O(nlogm)$

Code:

#include<cstdio>
#include<cstring>
#define maxn 1000010
using namespace std;
typedef long long LL;
LL r[maxn],d[maxn],s[maxn],t[maxn],S[maxn],last;
int n,m;
int judge(int x)
{
	if (x>last) //和栈顶关系
	for (int i=last+1;i<=x;i++)
	{
		S[s[i]]+=d[i];
		S[t[i]+1]-=d[i];//S维护差分信息
	}
	if (x<last)
	for (int i=x+1;i<=last;i++)
	{
		S[s[i]]-=d[i];
		S[t[i]+1]+=d[i];
	}
	int sum=0;
	last=x;
	for (int i=1;i<=n;i++)
	{
		sum+=S[i];//前缀和还原差分
		if (sum>r[i]) return 0;
	}
	return 1;
}
int main()
{
	
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
		scanf("%lld",&r[i]);
	for (int i=1;i<=m;i++)
		scanf("%lld%lld%lld",&d[i],&s[i],&t[i]);
	int l=1,r=m,ans=0;
	last=0;
	while (l<=r)
	{
		int mid=(l+r)>>1;
		if (!judge(mid)) {ans=mid;r=mid-1;}
		else l=mid+1;
	}
	if (!ans) puts("0");
	else printf("-1\n%d",ans);
	return 0;
}

草酸君似乎还有个无敌的$O(n+m)$做法

先把订单全部用上,那么必定有很多天教室数是小于0的。那么我们可以从后往前删除订单。

然后一样是差分模拟,当这天教室数小于0,就把当前订单删除,直到这天教室数合法。

因为是删除订单,所以以前的教室一定合法。

删除订单的时候注意是维护差分数组还是前缀和的值。

Code:

#include<bits/stdc++.h>
#define maxn 1000010
using namespace std;
typedef long long LL;
#define G c=getchar()
inline LL read()
{
	LL x=0,f=1;char G;
	while(c>57||c<48){if(c=='-')f=-1;G;}
	while(c>47&&c<58)x=x*10+c-48,G;
	return x*f;
}
LL w[maxn],dt[maxn],c[maxn],l[maxn],r[maxn],cur=0;
int main()
{
	int n=read(),m=read(),M=m;
	for(int i=1;i<=n;i++)dt[i]=(w[i]=read())-w[i-1];
	for(int i=1;i<=m;i++)
		c[i]=read(),l[i]=read(),r[i]=read()+1,dt[l[i]]-=c[i],dt[r[i]]+=c[i];
	for(int i=1;i<=n;i++)
		for(cur+=dt[i];cur<0;m--)
			if(l[m]>i)dt[l[m]]+=c[m],dt[r[m]]-=c[m];
			else if(r[m]>i)cur+=c[m],dt[r[m]]-=c[m];
	if(m==M)puts("0");
	else printf("-1\n%d",m+1);
	return 0;
}
Category: NOIP | Tags: 二分 模拟栈 | Read Count: 860

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com