您的位置:首页 > 其它

hdu 4768 Flyer【二分】

2015-05-07 19:09 453 查看
题目链接: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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: