题目大意:给出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
#include
#include
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; }