hdu4768Flyer(二分查找)

题目链接:点击打开链接

题意描述:给定一些线段,线段的斜率为Ci,y取值范围为[Ai,Bi],现在每个线段都会覆盖一些整数y,其中有一个整数y被覆盖了奇数次,找出它?


解题思路:

由于Bi最大为2^31次方,但我们可以在O(1)的时间内求的每条线段在某个区间内覆盖的点数,所以此题可以用二分查找,每次二分该区间点数总和为奇数的区间

,知道找到答案即可。


代码:

#include <cstdio>
#include <iostream>
using namespace std;
struct node
{
    int a;
    int b;
    int c;
} d[20010];
int n;
unsigned long long solve(int l,int r)
{
    unsigned long long ans=0;
    for(int i=0; i<n; i++)
    {
        int tl=max(l,d[i].a);
        int tr=min(r,d[i].b);
        if(tr>=tl)
        {
            if(d[i].c>0)
            {
                int mx=(tr-d[i].a)/d[i].c;
                int nx;
                if((tl-d[i].a)%d[i].c==0)
                    nx=(tl-d[i].a)/d[i].c;
                else
                    nx=(tl-d[i].a)/d[i].c+1;
                ans+=(mx-nx+1);
            }
            else
            {
                if(d[i].a>=tl&&d[i].a<=tr)
                    ans++;
            }
        }
    }
    return ans;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0; i<n; ++i)
            scanf("%d%d%d",&d[i].a,&d[i].b,&d[i].c);
        int l=1,r=(int)(((long long)1<<31)-1);
        if(solve(l,r)%2==0)
        {
            printf("DC Qiang is unhappy.\n");
            continue;
        }
        while(l<r)
        {
            int mid=(int)(((long long)l+r)/2);
            unsigned long long tmp=solve(l,mid);
            if(tmp>=0&&tmp%2)
                r=mid;
            else
                l=mid+1;
        }
        printf("%d %I64u\n",l,solve(l,l));
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值