题意:
给定若干个等差序列,这些个等差序列中每个元素出现的次数为偶数才算正常,现在有一个BUG:仅有一个元素出现了奇数次,让你找出这个元素和它出现的次数!
题解:
找特性:仅有一个元素出现了奇数次。举个栗子。
1 2 3 4 5 6 7 8 9 10
4
1 2 3 4 5
6 7 8 9 10
很明显bug元素是4。也就是前面的元素1 2 3 和后面的元素 5 6 7 8 9 10都出现了偶数次。
规律出来了:
<=X的元素个数为偶数的时候,说明bug元素>X,<=X的元素个数为奇数的时候,说明bug元素<=X。二分的有序性就出来了!
PS:输入故意刁难~~~
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<vector>
#include<functional>using namespace std;typedef unsigned long long ULL;vector<ULL>x,y,z;int N;//数据组数char buf[100];
bool input()
{x.clear();y.clear();z.clear();bool have=false;while(gets(buf)){if(!strlen(buf))if(have)break;else continue;ULL xx,yy,zz;sscanf(buf,"%I64d%I64d%I64d",&xx,&yy,&zz);have=true;x.push_back(xx);y.push_back(yy);z.push_back(zz);}N=x.size();return have;
}ULL Countsum(ULL mid)
{ULL sum=0;for(int i=0;i<N;i++){if(mid>=y[i])sum+=(y[i]-x[i])/z[i]+1;else if(mid>=x[i])sum+=(mid-x[i])/z[i]+1;}return sum;}int main()
{while(input()){ULL lb=0,ub=0xffffffff;//42亿多点while(ub-lb>1){ULL mid=(lb+ub)>>1;if(Countsum(mid)&1)ub=mid;//出现奇数,缩小范围(mid变小)去找最优可行解。else lb=mid;}if((lb+1)==0xffffffff)puts("no corruption");//没有的话,lb一直往右走。elsecout<<ub<<' '<<Countsum(ub)-Countsum(ub-1)<<endl;//最后的BUG数一定是给ub了!}
}