二分好题。
怎么二分呢?反正我是没想出来。
看了题解。
因为只有一个为奇数的点,所以对于一个位置x,求出区间[0, x]的教总和,如果为奇数,说明x取大了;否则x取小了(妙啊)。
虽然答案在int内,但是L + R可能会爆int,导致有几个点TLE了,所以还是都开long long 吧。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 2e5 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = ans * + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int n;
struct Node
{
ll s, e, d;
}t[maxn]; ll calc(ll x)
{
ll ret = ;
for(int i = ; i <= n; ++i)
{
if(t[i].s > x) continue;
ret += (min(x, t[i].e) - t[i].s) / t[i].d + ;
}
return ret;
} int main()
{
int T = read();
while(T--)
{
n = read(); ll Max = ;
for(int i = ; i <= n; ++i) t[i].s = read(), t[i].e = read(), t[i].d = read(), Max = max(Max, t[i].e);
ll L = , R = Max;
if(!(calc(R) & )) {puts("Poor QIN Teng:( "); continue;}
while(L < R)
{
ll mid = (L + R) >> ;
if(calc(mid) & ) R = mid;
else L = mid + ;
}
write(L), space, write(calc(L) - calc(L - )), enter;
}
return ;
}