我们发现只有一个奇数的点,所以这题可以运用前缀和,因为如果前缀和是奇数,那么因为偶数+偶数=偶数 奇数+偶数=奇数 小学知识,那么奇数一定在左面,否则在右面,这样就可以用二分了
但题目中说需要求出奇数点有多少个人,可以利用前缀和的基本性质:s[i]-s[i-1]=a[i],就可以了
看下代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=200020;
int n;
struct pj{ll s, e, d; } a[maxn];
int read() {
int x=0, f=1; char c=getchar();
for (; c<'0'||c>'9'; c=getchar()) if(c=='-') f=0;
for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
return f?x:-x;
}
ll chk(ll x) {
ll ans=0;
for (int i=1; i<=n; ++i)
if(x>=a[i].s)
ans+=(min(x, a[i].e)-a[i].s)/a[i].d+1;
return ans;
}
int main() {
int T=read();
while(T--) {
n=read();
for (int i=1; i<=n; ++i)
a[i].s=1ll*read(), a[i].e=1ll*read(), a[i].d=1ll*read();
ll l=0, r=2147483647;
while(l<r) {
ll mid=(l+r)>>1;
if(chk(mid)&1) r=mid; else l=mid+1;
}
if(l) printf("%lld %lld\n", l, chk(l)-chk(l-1));
else printf("Poor Qin Teng:(\n");
}
return 0;
}