HDU--4768

题目:

Flyer

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4768

分析:二分。只需要注意到最多只有一个为奇数,则可以首先求出学生获得的总的传单数,为奇数时,二分找到答案。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 #define LL long long
 8 #define maxn 20005
 9 struct N
10 {
11     LL now,lim,add;
12 }p[maxn];
13 int n;
14 int main()
15 {
16     while(scanf("%d",&n)!=EOF)
17     {
18         LL l=99999999999LL,r=0,sum=0;
19         for(int i=0;i<n;i++)
20         {
21             scanf("%I64d%I64d%I64d",&p[i].now,&p[i].lim,&p[i].add);
22             l=min(l,p[i].now);r=max(r,p[i].lim);
23             sum+=(p[i].lim-p[i].now)/p[i].add+1;
24         }
25         LL sum1,sum2,temp1,temp2,pos;
26         if(sum&1)
27         {
28             while(l<r)
29             {
30                 LL m=(l+r)>>1;
31                 sum1=0;sum2=0;
32                 for(int i=0;i<n;i++)
33                 {
34                     temp1=min(m,p[i].lim);
35                     temp2=min(r,p[i].lim);
36                     if(temp1>=p[i].now)
37                     sum1+=(temp1-p[i].now)/p[i].add+1;
38                     if(temp2>=p[i].now)
39                     sum2+=(temp2-p[i].now)/p[i].add+1;
40                 }
41                 sum2-=sum1;
42                 if(sum1&1)r=m;
43                 else l=m+1;
44                 if(l==r)
45                 {
46                     pos=l;
47                     break;
48                 }
49             }
50             sum1=0;
51             for(int i=0;i<n;i++)
52             {
53                 if((pos<=p[i].lim)&&(pos>=p[i].now)&&(((pos-p[i].now)%p[i].add)==0))
54                 sum1++;
55             }
56             printf("%I64d %I64d\n",pos,sum1);
57         }
58         else printf("DC Qiang is unhappy.\n");
59     }
60     return 0;
61 }
View Code

 

posted @ 2013-09-28 19:31  EtheGreat  阅读(266)  评论(0编辑  收藏  举报