题意
传送门 POJ 3484
求整个集合中唯一一个出现次数为奇数的值。对于每一输入行,其代表的数列是有序的,直接二分答案,计算小于等于当前值数字的个数。单调性在于,偶数相加仍为偶数,加上唯一的一个奇数后,后续求和都是奇数。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define abs(x) ((x) < 0 ? -(x) : (x))
#define INF 0x3f3f3f3f3f
#define delta 0.85
#define eps 1e-5
#define PI 3.14159265358979323846
#define MAX_N 20000
using namespace std;
typedef unsigned long long LL;
int N;
LL X[MAX_N], Y[MAX_N], Z[MAX_N];
char buff[128];
bool read(){
N = 0;
int p;
while((p = (gets(buff) != NULL)) && buff[0] >= '0' && buff[0] <= '9'){
sscanf(buff, "%lld%lld%lld", X + N, Y + N, Z + N);
++N;
}
return p || N;
}
LL C(int x){
LL s = 0;
for(int i = 0; i < N; i++){
if(X[i] > x) continue;
s += (min(Y[i], x) - X[i]) / Z[i] + 1;
}
return s;
}
int main(){
while(read()){
// 读入空行
if(N == 0) continue;
LL lb = 0, ub = INF;
while(ub - lb > 1){
LL mid = (lb + ub) >> 1;
if(C(mid) & 1) ub = mid;
else lb = mid;
}
if(ub == INF) printf("no corruption\n");
else printf("%lld %lld\n", ub, C(ub) - C(ub - 1));
}
return 0;
}