zoukankan      html  css  js  c++  java
  • HDU 4768 Flyer(二分)

    题目链接: 传送门

    Flyer

    Time Limit: 1000MS     Memory Limit: 32768 K

    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+2C_i,…A_i+kC_i (A_i+kC_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
    

    解题思路:

    有n个社团,第i个社团有3个数a[i] b[i] c[i] 每个社团给学号小于等于b[i]且为a[i],a[i]+c[i]..a[i]+k*c[i]的人发传单。最多只有一个人被发到奇数次传单,求出他的编号和传单数目。如果没人,就输出 DC Qiang is unhappy.。
    如果有人收到奇数次传单,则所有社团发传单的总数显然是奇数。所以我们二分枚举传单总数。每次对于二分的结果mid检查学号[0,mid]区间内收到的传单总数是不是奇数。 如果是,那结果肯定在[0,mid]内,否则就在[mid+1,2^31]内,继续二分。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef __int64 LL;
    const long long  INF = (1LL << 31);
    struct node{
    	LL a,b,c;
    };
    node p[20005];
    int N;
    
    bool OK(LL x)
    {
    	LL sum = 0,tmp = 0;
    	for (int i = 0;i < N;i++)
    	{
    		tmp = min(x,p[i].b);
    		if (tmp >= p[i].a)
    		{
    			sum += (tmp - p[i].a)/p[i].c + 1;
    		}
    	}
    	if (sum & 1)
    		return true;
    	else
    		return false;
    }
    
    int main()
    {
    	while (~scanf("%d",&N))
    	{
    		LL maxx = 0,minn = INF,sum = 0;
    		memset(p,0,sizeof(p));
    		for (int i = 0;i < N;i++)
    		{
    			scanf("%I64d%I64d%I64d",&p[i].a,&p[i].b,&p[i].c);
    			maxx = max(maxx,p[i].b);
    			minn = min(minn,p[i].a);
    			sum += (p[i].b - p[i].a)/p[i].c + 1;
    		}
    		//cout << minn << " " << maxx << endl;
    		if (!(sum & 1))
    		{
    			printf("DC Qiang is unhappy.
    ");
    			continue;
    		}
    		LL left = minn,right = maxx;
    		while (left < right)
    		{
    			LL mid = left +((right-left)>>1);
    			if (OK(mid))
    			{
    				right = mid;
    			}
    			else
    			{
    				left = mid + 1;
    			}
    		}
    		//cout << left << " " << right << endl;
    		LL cnt = 0;
    		for (int i = 0;i < N;i++)
    		{
    			if (right >= p[i].a && right <= p[i].b && (right - p[i].a) % p[i].c == 0)
    			{
    				cnt++;
    			}
    		}
    		printf("%I64d %I64d
    ",right,cnt);
    	} 
    	return 0;
    }
    
  • 相关阅读:
    hdu 2222 Keywords Search 模板题
    AC自动机 (模板)
    7. 通过鼠标右键改变视角
    NGUI所见即所得之UIAtlasMaker , UIAtlas (2)
    6. 通过鼠标滑轮控制“镜头远近”
    5. Unity脚本的执行顺序
    4. 在Inspector面板中显示类中变量+ 拓展编辑器
    NGUI 的使用教程与实例(入门)(1 )
    1. 通过移动鼠标旋转摄像机观察模型
    C#面试题
  • 原文地址:https://www.cnblogs.com/ZhaoxiCheung/p/5693735.html
Copyright © 2011-2022 走看看