牛客练习赛108

风间

分析:

暴力

实现:

int a[N], b[N];
void solve()
{
    res = 0;
    scanf("%lld", &n);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &a[i]);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &b[i]);
 
    for (int i = 1; i <= n; i++)
    {
        if (abs(a[i] - b[i]) & 1)
        {
            puts("-1");
            return;
        }
        res += abs(a[i] - b[i]) / 2;
        int t = a[i] - b[i];
        if (i == n && t != 0)
        {
            puts("-1");
            return;
        }
        if (t == 0)
            continue;
        else if (t > 0)
            a[i + 1] += t;
        else if (t < 0)
            a[i + 1] += t;
               }
    printf("%lld\n", res);
}

梦迹

分析:

快速求出数组中满足 x + num ≤ w 的num的个数,树状数组维护前缀和
(数组中有0,加偏移量处理)

实现:

int tr[N], a[N];
int lowbit(int x)
{
    return x & -x;
}
void update(int x, int c) // 位置x加c
{
    for (int i = x; i <= N; i += lowbit(i))
        tr[i] += c;
}
int query(int x) // 返回前x个数的和
{
    int res = 0;
    for (int i = x; i; i -= lowbit(i))
        res += tr[i];
    return res;
}
void solve()
{
    cin >> n >> q >> w;
    w += 2;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        a[i]++;
        update(a[i], 1);
        res += query(w - a[i]);
    }

    for (int i = 1, pos, x; i <= q; i++)
    {
        cin >> pos >> x;
        x++;
        int num = a[pos];
        res -= query(w - num);
        update(a[pos], -1);
        a[pos] = x;
        update(x, 1);
        res += query(w - x);
        cout << res << endl;
    }
}
posted @ 2023-05-26 13:32  347Foricher  阅读(12)  评论(0编辑  收藏  举报