2013 ACM/ICPC Asia Regional Changchun Online Problem J & hdu4768 Flyer(二分)

来源:互联网 发布:安卓沙箱软件 编辑:程序博客网 时间:2024/06/11 12:07

题目请戳这里

题目大意:给n个三元组(ai,bi,ci),那么对于y = ci*x + ai(ai <= y <= bi,x >= 0),求所有三元组产生的y中,出现次数为奇数的数以及出现次数。数据保证最多存在一个数出现奇数次。如果没有数出现奇数次,输出一句话。

题目分析:从出现奇数次作为突破口。首先对于某个三元组(ai,bi,ci),yi = ci * x + ai,yi <= bi,那么可以确定这个三元组产生了(bi - ai)/ci + 1个数,那么统计所有三元组产生的数的总和,如果为偶数,那么一定不存在出现奇数次的数,直接输出那句话。如果是奇数,那么我们只需要找到这个数即可。

这个数可能很大,给每个整数开个计算器显然不可能。对所有三元组出现的数一一枚举也不可取,考虑到出现奇数次的只有一个数,那么我们可以在1~2^32范围内二分,寻找奇数区间,不断缩小范围,最后缩成一个点,那就是ans。

trick:1:二分的时候用__int64,会爆int;

2:ci可以为0!!当ci=0的时候,ai = bi;

详情请见代码:

#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<cstdlib>#include<cctype>#include<map>#include<vector>#include<set>#include<queue>#include<string>#include<ctime>using namespace std;const int N = 20005;const int M = 10000005;const int INF = 0x3f3f3f3f;const double eps = 1e-6;const double PI = acos(-1.0);typedef __int64 ll;struct node{    ll a,b,c,num;}p[N];ll n,maxx;ll fuck(ll x){    int ret = 0;    for(ll i = 1;i <= n;i ++)    {        if(p[i].c == 0)        {            if(x >= p[i].a)                ret ++;            continue;        }        if(x <= p[i].b && x >= p[i].a)        {            ret += ((x - p[i].a)/p[i].c + 1);        }else if(x > p[i].b)ret += p[i].num;    }    return ret;}void gao(){    ll l,r,mid;    l = 1;r = maxx;    ll tmp,tp;    ll ans;    ll tl = 0;    while(l <= r)    {        mid = (l + r)>>1;        tmp = fuck(mid);        if((tmp - tl) & 1)            r = mid - 1,ans = mid;        else            l = mid + 1,tl = tmp;    }   printf("%d %d\n",ans,fuck(ans) - tl);}int main(){    ll i;    while(scanf("%d",&n) != EOF)    {        ll sum = 0;        maxx = 0;        for(i = 1;i <= n;i ++)        {            scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].c);            if(p[i].c == 0)                p[i].num = 1;            else            {                p[i].num = (p[i].b - p[i].a)/p[i].c;                p[i].num ++;            }            sum += p[i].num;            if(maxx < p[i].b)                maxx = p[i].b;        }        if((sum&1) == 0)        {            puts("DC Qiang is unhappy.");            continue;        }        gao();    }    return 0;}


原创粉丝点击