HDU - 6274 Master of Sequence——二分

版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/83379922

按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;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/83379922