hdu 4768 Flyer(二分查找)

Flyer

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1537    Accepted Submission(s): 552

Problem Description

The new semester begins! Different kinds of student societies are all trying to advertise themselves, by giving flyers to the students for introducing the society. However, due to the fund shortage, the flyers of a society can only be distributed to a part
of the students. There are too many, too many students in our university, labeled from 1 to 2^32. And there are totally N student societies, where the i-th society will deliver flyers to the students with label A_i, A_i+C_i,A_i+2*C_i,…A_i+k*C_i (A_i+k*C_i<=B_i,
A_i+(k+1)*C_i>B_i). We call a student "unlucky" if he/she gets odd pieces of flyers. Unfortunately, not everyone is lucky. Yet, no worries; there is at most one student who is unlucky. Could you help us find out who the unfortunate dude (if any) is? So that
we can comfort him by treating him to a big meal!

Input

There are multiple test cases. For each test case, the first line contains a number N (0 < N <= 20000) indicating the number of societies. Then for each of the following N lines, there are three non-negative integers A_i, B_i, C_i (smaller than 2^31, A_i <=
B_i) as stated above. Your program should proceed to the end of the file.

Output

For each test case, if there is no unlucky student, print "DC Qiang is unhappy." (excluding the quotation mark), in a single line. Otherwise print two integers, i.e., the label of the unlucky student and the number of flyers he/she gets, in a single line.

Sample Input

2
1 10 1
2 10 1
4
5 20 7
6 14 3
5 9 1
7 21 12

Sample Output

1 1
8 1

Source

2013 ACM/ICPC Asia Regional Changchun
Online

二分查找,且要用64位整型,先统计标签数目,为偶数则必然不存在任何一个人为奇数的情况。

然后,在用二分查找。

#include"stdio.h"
#include"string.h"
#include"iostream"
using namespace std;
#define N 20005
#define inf 0x7fffffff
#define LL __int64
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
LL a[N],b[N],d[N];
int main()
{
    int i,n;
    while(~scanf("%d",&n))
    {
        LL sum,l,r,t;
        sum=r=0; l=inf;
        for(i=0;i<n;i++)
        {
            scanf("%I64d%I64d%I64d",&a[i],&b[i],&d[i]);
            t=(b[i]-a[i])/d[i];
            sum+=t+1;
            r=max(r,a[i]+t*d[i]);
            l=min(l,a[i]);
        }
        if(sum%2==0)
            printf("DC Qiang is unhappy.\n");
        else
        {
            LL mid,num,y;
            while(l<=r)
            {
                mid=(l+r)/2;
                num=0;
                sum=0;
                for(i=0;i<n;i++)
                {
                    if(a[i]>mid)
                        continue;
                    if(mid<=b[i])
                        t=(mid-a[i])/d[i];
                    else if(mid>b[i])
                        t=(b[i]-a[i])/d[i];
                    sum+=t+1;
                    if(a[i]+t*d[i]==mid||mid==a[i]) //统计边界点mid的数目
                        num++;
                    y=mid;
                }
                if(num%2) break;        //该点就是奇数点
                if(sum%2) r=mid-1;
                else l=mid+1;
            }
            printf("%I64d %I64d\n",y,num);
        }
    }
    return 0;
}

hdu 4768 Flyer(二分查找)

时间: 2024-08-13 11:17:58

hdu 4768 Flyer(二分查找)的相关文章

HDU 4768 Flyer (二分)

OJ题目:click here~~ 题目分析:n个[a  b] 区间,对于i 属于[a  b]  ,从a开始,间隔c ,即i = a , i = a + c , i = a + 2*c -- 将x[ i ] 加1 ,x[ i ] 初值为0 . 已知最多只有一个x[ i ] 为奇数.找到这个i , 和这个奇数. 由于最多只有一个奇数,且奇数 + 偶数 = 奇数.用二分夹逼出这个奇数的位置.找到这个位置,再计算这个奇数就很容易了. AC_CODE const int maxn = 20002; LL

HDU 1969 Pie (二分查找)

题目链接:click here~~ 题目大意:n块馅饼分给m+1个人,每一个人的馅饼必须是整块的.馅饼能够被切开.但不能组合,也不一定要所有分完,问你每一个人最大能分到多大体积的馅饼面积. [解题思路]:二分,对于每一个V值,我们枚举相应情况下人数P的多少,发现是单调递减的,因此二分查找区间,初始值left=0,right=inf;然后judge函数推断当前mid值是否能使得p>=m,因此累计ans=num[i]/mid,写的时候二分用的是while推断,怎么调试答案就是差了那么一点点.后来索性

hdu 4768 Flyer【二分】

题目链接: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,求那个同学收到传单数为奇数和这位同学 收到的传单数目,题目保证最多有一位同学收到传单为奇数. 分析:题目保证的那句话很重要,由于学生的数

HDU 4768 (二分区间)

题意:告诉n组A,B,C,按照A + k * C生成等差数列,问这n组数列中哪个数字出现了奇数次以及出现了几次,题目保证最多只会出现一个这种数字. 分析:读完题并没有思路,后来知道是二分区间,枚举是哪个数字出现了奇数次,算该数字之前一共有几个数字,如果是奇数个,说明答案就在[L , Mid]中. PS:之前用二分只是枚举具体要求的数字,原来枚举区间也可以.二分的时候 l = mid + 1,r = mid ;(一开始r = mid + 1,l = mid就无限循环,手算并没有错啊?很奇怪...)

HDU 5878---预处理+二分查找

给一个数n,让你求一个大于等于n的最小的满足题意中2^a*3^b*5^c*7^d的数字. 思路: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set&g

HDU 2578(二分查找)

686MS 1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 6 using namespace std; 7 8 int a[100010]; 9 10 int n; 11 12 bool bsearch(int key) 13 { 14 int lo = 0,hi = n-1,mid = lo+(hi-lo)/2; 15 whil

hdu 2141 Can you find it?(二分查找)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2141 题目大意:查找是否又满足条件的x值. 这里简单介绍一个小算法,二分查找. 1 /* 2 3 x^2+6*x-7==y 4 输入y 求x 精确度为10^-5 5 0=<x<=10000 6 7 */ 8 #include <iostream> 9 #include <cstdio> 10 using namespace std; 11 int main (void) 1

hdu 5592 ZYB&#39;s Premutation (线段树+二分查找)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=5592 Problem Description ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutation,now he ask you to  restore the premutation.Pair (i,j)(i<j) is considered as a reverse

STL之二分查找:hdu 5178 ( BestCoder Round #31 1001 )

STL包含四种不同的二分查找算法,binary_search    lower_bound  upper_bound   equal_range.他们的作用域是已经排序好的的数组. ★binary_search试图在已排序的[first, last)中寻找元素value.如果找到它会返回true,否则返回false,它不返回查找位置. ★iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素. ★iterat