AcWing 120 防線(二分)
阿新 • • 發佈:2020-07-15
解題思路
這題可以很巧妙的用二分來解決,因為最多隻含一個奇數,所以我們可以二分奇數位置。如果總的防具數是偶數,那麼就沒有破綻,否則,如果左區間的防具數是奇數,那麼答案肯定在左區間,如果右區間的防具數是奇數,那麼答案就在右區間。
程式碼
const int maxn = 2e5+10; struct INFO { ll s,e,d; } info[maxn]; int n; bool check(ll x) { ll sum = 0; for (int i = 1; i<=n; ++i) if (info[i].s<=x) sum += 1+(min(x,info[i].e)-info[i].s)/info[i].d; return sum&1; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for (int i = 1; i<=n; ++i) scanf("%lld%lld%lld",&info[i].s,&info[i].e,&info[i].d); ll l = 0, r = 12345678910LL; while(l<r) { ll mid = (l+r)>>1; if (check(mid)) r = mid; else l = mid+1; } if (r==12345678910LL) printf("There's no weakness.\n"); else { int cnt = 0; for (int i = 1; i<=n; ++i) if (info[i].s==l || (info[i].e>=l && info[i].s<=l && (l-info[i].s)%info[i].d==0)) ++cnt; printf("%lld %d\n",l,cnt); } } return 0; }