题目链接:点击打开链接
题意描述:给定一些线段,线段的斜率为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;
}