zoukankan      html  css  js  c++  java
  • Codeforces Round #489 (Div. 2) E

    E - Nastya and King-Shamans

    题目大意:有n个数,每一次操作更改一个数,每次操作之后问你是否有一个数等于其前面所有数的和。

    思路:好题,想了很久没想出来,看了题解,主要思想就是满足条件的数会成倍增长,如我们知道了

    1 - i 里面没有满足条件的数, 那么我们找一个最小的 j 满足 a[ j ] >= sum(1, i),j就可能成为一个答案,

    我们check一下,如果可以就是这个点,如果不行那么 不可能前缀就从 1 - i 变成了 1 - j, 这个过程最多

    执行log(max(a[ i ])) 次, 因为前缀和每次操作至少×2,这样我们用线段树维护区间和,区间最大值就好了。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int, int>
    
    using namespace std;
    
    const int N = 2e5 + 7;
    const int M = 1e6 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 +7;
    
    LL mx[N << 2], sum[N << 2];
    int n, q;
    
    void update(int pos, int v, int l, int r, int rt) {
        if(l == r) {
            sum[rt] = v;
            mx[rt] = v;
            return;
        }
        int mid = l + r >> 1;
        if(pos <= mid) update(pos, v, l, mid, rt << 1);
        else update(pos, v, mid + 1, r, rt << 1 | 1);
        sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
        mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
    }
    
    LL getSum(int L,int R, int l, int r, int rt) {
        if(l >= L && r <= R) return sum[rt];
        int mid = l + r >> 1;
        LL ans = 0;
        if(L <= mid) ans += getSum(L, R, l, mid, rt << 1);
        if(R > mid) ans += getSum(L, R, mid + 1, r, rt << 1 | 1);
        return ans;
    }
    
    void getMxId(int L, int R, LL v, int l, int r, int rt, LL &ret, LL &id) {
        if(mx[rt] < v || id != -1) return;
        if(l == r) {
            id = l;
            ret = mx[rt];
            return;
        }
        int mid = l + r >> 1;
        if(L <= mid) getMxId(L, R, v, l, mid, rt << 1, ret ,id);
        if(R > mid) getMxId(L, R, v, mid + 1, r, rt << 1 | 1, ret, id);
    }
    
    int cal() {
        if(getSum(1, 1, 1, n, 1) == 0) return 1;
        int now = 1;
        while(now < n) {
            LL sum = getSum(1, now, 1, n, 1), ret = -1, id = -1;
            getMxId(now + 1, n, sum, 1, n, 1, ret, id);
            if(id == -1) return -1;
            sum = getSum(1, id - 1, 1, n, 1);
            if(sum == ret) return id;
            now = id;
        }
        return -1;
    }
    
    int main() {
        scanf("%d%d", &n, &q);
        for(int i = 1; i <= n; i++) {
            int x; scanf("%d", &x);
            update(i, x, 1, n, 1);
        }
        while(q--) {
            int pos, v; scanf("%d%d", &pos, &v);
            update(pos, v, 1, n, 1);
            printf("%d
    ", cal());
        }
        return 0;
    }
    /*
    */
  • 相关阅读:
    把影响集中到一个点
    How to avoid Over-fitting using Regularization?
    适定性问题
    Numerical Differentiation 数值微分
    What Every Computer Scientist Should Know About Floating-Point Arithmetic
    Generally a good method to avoid this is to randomly shuffle the data prior to each epoch of training.
    What is the difference between iterations and epochs in Convolution neural networks?
    Every norm is a convex function
    Moore-Penrose Matrix Inverse 摩尔-彭若斯广义逆 埃尔米特矩阵 Hermitian matrix
    perl 类里的函数调用其他类的函数
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9209760.html
Copyright © 2011-2022 走看看