【BZOJ 1271】 [BeiJingWc2008]秦腾与教学评估

1271: [BeiJingWc2008]秦腾与教学评估

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 1184   Solved: 411
[ Submit][ Status]

Description

【BZOJ 1271】 [BeiJingWc2008]秦腾与教学评估_第1张图片

Input

【BZOJ 1271】 [BeiJingWc2008]秦腾与教学评估_第2张图片

Output

【BZOJ 1271】 [BeiJingWc2008]秦腾与教学评估_第3张图片

Sample Input

Sample Output

【BZOJ 1271】 [BeiJingWc2008]秦腾与教学评估_第4张图片

HINT

【BZOJ 1271】 [BeiJingWc2008]秦腾与教学评估_第5张图片


二分。


一道非常神奇的题。。


一定要注意到题目中说最多有一个地方是奇数个人!!


那么我们二分pos,如果0-pos的人数为偶数,那么ans一定在pos+1-r之间,否则在0-pos之间。


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define M 200005
#define LL long long
using namespace std;
LL s[M],e[M],d[M];
int n;
LL minn(LL a,LL b)
{
	return a<b?a:b;
}
LL maxx(LL a,LL b)
{
	return a>b?a:b;
}
LL calc(LL r)
{
	int ans=0;
	for (int i=1;i<=n;i++)
	{
		if (s[i]>r) continue;
                ans=ans+(minn(r,e[i])-s[i])/d[i]+1LL;
	}
	return ans;
}
int main()
{
	int T;
        scanf("%d",&T);
	while (T--)
	{
		scanf("%d",&n);
		LL l=0,r=0;
		for (int i=1;i<=n;i++)
			scanf("%lld%lld%lld",&s[i],&e[i],&d[i]),r=maxx(r,e[i]);
		if (!(calc(r)&1LL))
		{
			printf("Poor QIN Teng:(\n");
			continue;
		}
		while (l<r)
		{
			LL m=(l+r)>>1;
			if (calc(m)&1LL) r=m;
			else l=m+1LL;
		}
		LL ans=0;
		for (int i=1;i<=n;i++)
		{
			if (e[i]<l||s[i]>l) continue;
			LL k=(l-e[i])/d[i];
			if (k*d[i]==l-e[i]) ans++;
		}
		printf("%lld %lld\n",l,ans);
	}
	return 0;
}



感悟:

1.wa那么多次是因为long long的问题,虽然输入都在int范围内,但中间有相加的情况,一加就超了。。


2.充分利用题目中给的信息~

你可能感兴趣的:(二分,OI,bzoj)