码迷,mamicode.com
首页 > 其他好文 > 详细

●洛谷P1083 借教室

时间:2018-03-10 20:29:53      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:二分答案   def   bool   break   sum   pac   std   for   gpo   

题链:

https://www.luogu.org/problemnew/show/P1083
题解:

二分,差分


显然具有二分性:
如果只考虑1~p个人,就会在某一天无法满足,
那么显然只考虑1~[p+1,M]个人都会无法满足。
所以二分答案mid,第1~mid个人是否导致了无法满足,
然后对于每个人,现在其对应的区间的左右端点打上差分标记,
然后O(n)扫一遍,看看是否在某一天会无法满足。
并以此来缩小l或r的范围。


代码:

 

#include<bits/stdc++.h>
#define MAXN 1000006
using namespace std;
struct Query{
	int d,l,r;
}A[MAXN];
int N,M;
int R[MAXN],C[MAXN];
bool wrong(int p){
	static int sum,fg; sum=0; fg=0;
	for(int i=1;i<=p;i++)
		C[A[i].l]+=A[i].d,C[A[i].r+1]-=A[i].d;
	for(int i=1;sum+=C[i],i<=N;i++) 
		if(sum>R[i]){fg=1; break;}
	for(int i=1;i<=p;i++)
		C[A[i].l]-=A[i].d,C[A[i].r+1]+=A[i].d;
	return fg;
}
int binary(){
	int l=1,r=M,mid,ret=0;
	while(l<=r){
		mid=(l+r)>>1;
		if(wrong(mid)) ret=mid,r=mid-1;
		else l=mid+1; 
	}
	return ret;
}
int main(){
	scanf("%d%d",&N,&M);
	for(int i=1;i<=N;i++) scanf("%d",&R[i]);
	for(int i=1;i<=M;i++) scanf("%d%d%d",&A[i].d,&A[i].l,&A[i].r);
	int ans=binary();
	if(!ans) printf("%d\n",ans);
	else printf("%d\n%d\n",-1,ans);
	return 0;
}

 

  

 

●洛谷P1083 借教室

标签:二分答案   def   bool   break   sum   pac   std   for   gpo   

原文地址:https://www.cnblogs.com/zj75211/p/8541636.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!