不能暴,会超时,要用LL,否则结果不对,采用二分,既然是找奇数,那么可以计算出所有的社团所发放传单的数目和,如果为偶数,那么必然不存在任何一个人为奇数;如果存在,那么可以不断二分学生的下标从而找到是在哪个位置
#include <iostream>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <vector>
#include <cstring>
#include <algorithm>
#define INF 0x7ffffffffffLL
#define N 20010
#define LL long long
using namespace std;
LL num[N][3];
int main()
{
// freopen("in.txt","r",stdin);
int n;
while(scanf("%d", &n) != EOF){
LL MIN = INF, MAX = 0, sum = 0;
for(int i = 0; i < n; ++i){
scanf("%I64d %I64d %I64d", &num[i][0], &num[i][1], &num[i][2]);
MIN = num[i][0] > MIN ? MIN : num[i][0];
LL cnt = (num[i][1] - num[i][0]) / num[i][2];
LL count = cnt * num[i][2] + num[i][0];
MAX = count > MAX ? count : MAX;
sum += cnt + 1;
}
if(sum % 2 == 0) printf("%s\n", "DC Qiang is unhappy.");
else {
LL x, y;
while(MIN <= MAX){
x = 0;
LL mid = (MIN + MAX) / 2;
sum = 0;
for(int i = 0; i < n; ++i)
if(mid >= num[i][0]) {
LL cnt = (mid - num[i][0]) / num[i][2];
if(num[i][1] <= mid) cnt = (num[i][1] - num[i][0]) / num[i][2];
LL count = cnt * num[i][2] + num[i][0];
sum += cnt + 1;
if(count == mid || num[i][0] == mid) ++x;
// printf("%d %d %d\n", count, mid, i);
y = mid;
}
if(x % 2 == 1) break;
if(sum % 2 == 0) MIN = mid + 1;
else MAX = mid - 1;
}
printf("%I64d %I64d\n", y, x);
}
}
return 0;
}