【ybtoj 高效进阶 1.3】 【二分】 防具布置
题目
解题思路
看一眼数据范围
裂开o(≧口≦)o
不可能用桶排
若pd(231-1)为偶数,则整道防线没有破绽
有破绽就会是奇数啊
因为只有一个破绽
二分破绽的位置
如果这个位置的防具总数是奇数
说明破绽在前面
否则在后
代码
#include<iostream>
#include<cstdio>
using namespace std;
long long l,r,s[200100],e[200100],d[200100],n,q;
long long pd(long long x)
{
long long sum=0;
for (int i=1;i<=n;i++)
if (s[i]<=x) //起始点在当前枚举的破绽位置前
sum+=(min(x,e[i])-s[i])/d[i]+1; //累计防具
return sum;
}
int main()
{
scanf("%lld",&q);
for (int i=1;i<=q;i++)
{
scanf("%lld",&n);
for (int j=1;j<=n;j++)
scanf("%lld%lld%lld",&s[j],&e[j],&d[j]);
l=0,r=2147483647;
if (pd(r)%2==0) //特判
{
printf("There's no weakness.\n");
continue;
}
while (l<r)
{
long long mid=(l+r)/2;
if (pd(mid) & 1)
r=mid;
else l=mid+1;
}
printf("%lld %lld\n",l,pd(l)-pd(l-1));
}
return 0;
}