HDU - 6274 Master of Sequence——二分
阿新 • • 發佈:2018-11-16
按a的值分組,處理一下餘數,二分一下就可以了
但是我二分上界設定的1e18,在計算過程中爆炸了,正確的上界應該是1e14
真的調了很久才意識到這個問題。。。
明天就打區域賽了。。。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1010; const int maxm = 1e5 + 10; const long long INF = 1e14; int T, N, M; ll a[100005], b[100005]; ll cnt, num[maxn][maxn]; bool judge(ll x, ll K) { ll ans = 0; for (int i = 1; i <= 1000; i++) { ans += x/i*num[i][0]-num[i][x%i+1]; } return (ans >= K); } ll solve(ll K) { ll l = 0, r = INF, mid; while (l <= r) { mid = (l + r)>>1; if (judge(mid, K)) r = mid - 1; else l = mid + 1; } return l; } int main() { scanf("%d", &T); while (T--) { scanf("%d %d", &N, &M); for (int i = 1; i <= N; i++) scanf("%lld", &a[i]); for (int i = 1; i <= N; i++) scanf("%lld", &b[i]); cnt = 0; memset(num, 0, sizeof(num)); for (int i = 1; i <= N; i++) { cnt += b[i]/a[i]; num[a[i]][b[i]%a[i]]++; } for (int i = 1; i <= 1000; i++) { for (int j = i-1; j >= 0; j--) { num[i][j] += num[i][j+1]; } } int op, x, y, k; while (M--) { scanf("%d", &op); if (op == 1) { scanf("%d %d", &x, &y); cnt -= b[x]/a[x]; for (int j = b[x]%a[x]; j >= 0; j--) num[a[x]][j]--; a[x] = y; cnt += b[x]/a[x]; for (int j = b[x]%a[x]; j >= 0; j--) num[a[x]][j]++; } else if (op == 2) { scanf("%d %d", &x, &y); cnt -= b[x]/a[x]; for (int j = b[x]%a[x]; j >= 0; j--) num[a[x]][j]--; b[x] = y; cnt += b[x]/a[x]; for (int j = b[x]%a[x]; j >= 0; j--) num[a[x]][j]++; } else { scanf("%d", &k); printf("%lld\n", solve(cnt+k)); } } } return 0; }