链接
题目描述
我们可以用三个整数 S, E 和 D 来描述一组防具。同一组防具是等距离排列的,从 S 开始,间距为 D,一直排到 E。(最后的防具不一定放在 E,但是一定是在)
只有一个地方(或者没有)的防具数量是单数,如果有就要求位置,否则输出 There’s no weakness.
样例输入
3
2
1 10 1
2 10 1
2
1 10 1
1 10 1
4
1 10 1
4 4 1
1 5 1
6 10 1
样例输出
1 1
There's no weakness.
4 3
思路
二分
我们设
S
i
S_{i}
Si为0~i的防具总和
然后我们直接二分到一个点是奇数的就可以了
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
ll T, n, aans, s[1000005], e[1000005], d[1000005];
ll minn(ll a, ll b)
{
if(a > b) return b;
return a;
}
ll check(ll x)
{
ll ans = 0;
for(int i = 1; i <= n; ++i)
if(s[i] <= x) ans += (minn(x, e[i]) - s[i]) / d[i] + 1;//求这段有多少个防具
return ans;
}
int main()
{
scanf("%lld", &T);
while(T--)
{
scanf("%lld", &n);
for(int i = 1; i <= n; ++i)
scanf("%lld%lld%lld", &s[i], &e[i], &d[i]);
if(check(2147483647) % 2 == 0) {
printf("There's no weakness.\n");
continue;
}
ll l = 0, r = 2147483647;
while(l <= r)
{
ll mid = (ll)(l + r) >> 1;
if(check(mid) % 2) aans = mid, r = mid - 1ll;
else l = mid + 1ll;
}
printf("%lld %lld\n", aans, check(aans) - check(aans - 1));
}
}