二分,只有有奇数 个防具的位置有破绽,但是整条防线上也最多只有一个位置有奇数个防具 为突破点,如果一个区间总共有奇数个防具那么可定就有有一个点的防具为奇数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=200010,inf=2147483647; struct node{ ll l,r,d; }a[N]; int n; bool check(ll k){ ll ret=0; for(int i=1;i<=n;++i){ if(a[i].l<=k){ ret+=(min(k,a[i].r)-a[i].l)/a[i].d+1; } } return ret%2; } int main(){ int T; scanf("%d",&T); while(T--){ ll l=inf,r=-inf; scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].d); l=min(a[i].l,l); r=max(a[i].r,r); } ll ans=-1,ans2=0; while(l<=r){ ll mid=(l+r)>>1; if(check(mid))r=mid-1,ans=mid; else l=mid+1; } if(ans==-1){ puts("There's no weakness."); continue; } for(int i=1;i<=n;++i){ if(a[i].l<=ans&&a[i].r>=ans){ if((ans-a[i].l)%a[i].d==0)++ans2; } } printf("%lld %lld ",ans,ans2); } return 0; }