Flyer HDU - 4768

HDU-4768 Flyer
题意:社团给1- 2 32 2^{32} 232编号的学生分发标签为i的宣传单,宣传单有n种,分发给编号是Ai,Ai+Ci,Ai+2Ci,…编号不超过Bi的学生,找出被发到传单为奇数的学生,保证最多只有一个。
在这里插入图片描述

题解:第一次见到二分是这种姿势的!因为只有包含有奇数的那个区间的区间和才会是奇数,简直妙极了…利用这个性质就可以二分区间了。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define IOS ios::sync_with_stdio(0),cin.tie(0)
#define sf(a) scanf("%d",&a)
#define dg(a) cout<<"#a"<<" "<<a<<endl
#define pi acos(double(-1))
using namespace std;
typedef long long ll;
const int N=2e4+10;
ll num[N][3];
int n,F;
typedef long long ll;
void findans(ll x)
{
    ll cnt=0;
    for(int i=1;i<=n;i++)
    {
        if(x>=num[i][0]&&x<=num[i][1]){
            if((x-num[i][0])%num[i][2]==0){
                cnt++;
            }
        }
    }
    if(cnt&1)cout<<x<<" "<<cnt<<endl;
    else cout<<"DC Qiang is unhappy."<<endl;
}
bool check(ll l,ll r)
{
    ll cnt=0;
    ll tp1=l,tp2=r;
    for(int i=1;i<=n;i++)
    {
        l=tp1,r=tp2;
        l=max(l,num[i][0]),r=min(r,num[i][1]);
        if(l>r)continue;
        l-=num[i][0],r-=num[i][0];
        ll res=r/num[i][2]+1;
        if(l!=0)
        {
            res-=(l-1)/num[i][2]+1;
        }
        cnt+=res;
    }
    if(cnt&1)return true;
    return false;
}
void solve()
{
    for(int i=1;i<=n;i++)
    {
        cin>>num[i][0]>>num[i][1]>>num[i][2];
    }
    ll l=1,r=ll(1)<<32;
    while(l<r)
    {
        ll mid=(l+r)>>1;
        if(check(l,mid))
        {
            r=mid;
        }
        else l=mid+1;
    }
    findans(r);
    return;
}
int main ()
{
    IOS;
    while(cin>>n)
    solve();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值