POJ 3484 二分

题意

传送门 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;
}
发布了91 篇原创文章 · 获赞 1 · 访问量 1601

猜你喜欢

转载自blog.csdn.net/neweryyy/article/details/105232190