[HNUOJ1140] Daily Division(树状数组+二分)

传送门:Daily Division

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e5+5;
int n, q;
ll a[maxn], ft[maxn];

int lowbit(int x)
{
    return x & -x;
}

void update(int x, int val)
{
    while(x <= n)
    {
        ft[x] += val;
        x += lowbit(x);
    }
}

ll query(int x)
{
    ll ret = 0;
    while(x > 0)
    {
        ret += ft[x];
        x -= lowbit(x);
    }
    return ret;
}

ll getDiv(int pos)
{
    ll lsum = 0, rsum = 0, msum = 0;
    if(pos != 1)
        lsum = query(pos-1);
    if(pos != n)
        rsum = query(n) - query(pos);
    msum = query(pos) - query(pos-1);
    if(msum & 1)
    {
        if(lsum <= rsum)
            ++lsum;
        else
            ++rsum;
    }
    return lsum-rsum;
}

void read()
{
    cin >> n >> q;
    for(int i = 1; i <= n; ++i)
    {
        cin >> a[i];
        update(i, a[i]);
    }
}

void solve()
{
    int I, x;
    while(q--)
    {
        cin >> I >> x;
        update(I+1, -(query(I+1)-query(I))); //清0
        update(I+1, x); //更新

        int l = 1, r = n;
        while(r-l > 1)
        {
            int mid = l + ((r-l)>>1);
            if(getDiv(mid) <= 0)
                l = mid;
            else
                r = mid;
        }

        ll minDiv = INF, div[3];
        int ans = 0;
        if(l == 1)
            div[0] = INF;
        else
            div[0] = abs(getDiv(l-1));
        div[1] = abs(getDiv(l));
        if(l == n)
            div[2] = INF;
        else
            div[2] = abs(getDiv(l+1));

        for(int i = 0; i < 3; ++i)
            if(minDiv > div[i])
            {
                minDiv = div[i];
                ans = l-2+i;
            }
        cout << ans << endl;
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    read();
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/HNUCSEE_LJK/article/details/100516504