题目大意:给出N个X Y Z组合,其中X Y Z组合能够输出 X, X + Z, X + 2 * Z… X + K * Z(X+K * Z <= Y)问这些输出的数中,有哪个数是输出奇数次的
解题思路:输出保证最多只有一个奇数
假设J是输出奇数次的那个数,那么小于J的所有输出的数的个数之和就为偶数,大于等于J的所有输出的数的个数之和为奇数
如果以i为标准,输出小于等于i的所有数之和,i从小到大变化的话,就会有如下的形式
偶偶偶偶偶偶奇奇奇。。。第一个奇刚好是J
(具体的可以自己验证)
通过上面的规律,就可以通过二分搜索来求得J了
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 50010
typedef long long ll;
ll X[maxn], Y[maxn], Z[maxn];
int cnt;
char str[maxn];
ll judge(ll mid) {
ll Sum = 0;
for(int i = 0; i < cnt; i++) {
if(mid < X[i])
continue;
ll t = min(mid, Y[i]);
Sum += (t - X[i])/ Z[i] + 1;
}
return Sum;
}
void solve() {
cnt = 1;
X[0] = 0;
sscanf(str,"%lld%lld%lld", &X[0], &Y[0], &Z[0]);
if(!X[0])
return ;
while(gets(str) && str[0]) {
sscanf(str,"%lld%lld%lld", &X[cnt], &Y[cnt], &Z[cnt]);
cnt++;
}
ll l = 0, r = 1LL << 32;
while(l < r) {
ll mid = (l + r) / 2;
if(judge(mid) % 2)
r = mid;
else
l = mid + 1;
}
if(l == (1LL << 32))
printf("no corruption\n");
else
printf("%lld %lld\n",l, judge(l) - judge(l - 1));
}
int main() {
while(gets(str))
solve();
return 0;
}
时间: 2024-10-26 00:26:24