标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4768
题意:学校有N个社团,新学期开始之际这N个社团发传单,它们发
传单是有规律的,有三个数组A[maxn],B[maxn],C[maxn],第i个设
团值发给编号为x的同学,其中x=A[i]+k*C[i]且k为整数,x小于等于
B[i];学校学生标号1~2^31,求那个同学收到传单数为奇数和这位同学
收到的传单数目,题目保证最多有一位同学收到传单为奇数。
分析:题目保证的那句话很重要,由于学生的数目很大,所以不能考虑
枚举、暴力,联想到奇偶的传递性,在这道题中:偶+偶=偶,奇+偶=奇,
这样可以用二分来解决,mid=(l+r), sum=cal(mid)计算出1-mid
所有学生收到的传单总和,若sum为偶数则说明1-mid中不存在那位同学
否则存在,这样时间这个问题就迎刃而解了,做题真的需要思维联系,能够
充分利用所学知识,不然就白瞎了。
献上代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxh=20000+10;
const long long int inf=(1LL<<31);
long long int A[maxh],B[maxh],C[maxh];
long long int cal(long long int mid,int n)
{
long long int top,sum=0;
for(int i=0;i<n;i++)
{
top=min(mid,B[i]);
if(top>=A[i])
sum+=(top-A[i])/C[i]+1;
}
return sum;
}
int main()
{
int n;
long long int l,r,mid;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
scanf("%I64d%I64d%I64d",&A[i],&B[i],&C[i]);
l=0,r=inf;
while(l<r)
{
mid=(l+r)/2;
if(cal(mid,n)%2)r=mid;
else l=mid+1;
}
if(l==inf)
printf("DC Qiang is unhappy.\n");
else
printf("%I64d %I64d\n",l,cal(l,n)-cal(l-1,n));
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/letterwuyu/article/details/45565197