• Codeforces 808D. Array Division


    题目大意

    给定你一个长为(n)的序列,问能否在最多一次取出某一元素然后插入到某一点后可以将整个序列分成两段使得其两段的元素之和相同.
    (n leq 10^5)

    题解

    发现插入操作实际上是让某一个元素与端点周围的元素交换。
    维护一个支持插入和查找元素是否存在的ds即可.

    #include <set>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(ll &x){
        x=0;char ch;bool flag = false;
        while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
        while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    #define rg register int
    #define rep(i,a,b) for(rg i=(a);i<=(b);++i)
    #define per(i,a,b) for(rg i=(a);i>=(b);--i)
    const int maxn = 100010;
    ll a[maxn],pre[maxn],suf[maxn];
    multiset<ll>S;
    int main(){
        ll n;read(n);
        rep(i,1,n) read(a[i]),pre[i] = pre[i-1] + a[i];
        per(i,n,1) suf[i] = suf[i+1] + a[i];
        rep(i,1,n){
            S.insert(a[i]);
            if(pre[i] == suf[i+1]){
                puts("YES");
                return 0;
            }
            ll x = pre[i] - suf[i+1] + 2LL*a[i+1];
            if(x&1) continue;
            x >>= 1;
            if(S.count(x) != 0){
                puts("YES");
                return 0;
            }
        }
        S.clear();
        per(i,n,1){
            S.insert(a[i]);
            ll x = suf[i] - pre[i-1] + 2LL*a[i-1];
            if(x&1) continue;
            x >>= 1;
            if(S.count(x) != 0){
                puts("YES");
                return 0;
            }
        }
        puts("NO");
        return 0;
    }
    
    
    
  • 相关阅读:
    no-useless-call (Rules) – Eslint 中文开发手册
    Java 8 Stream
    CSS3 ,checked 选择器
    MySQL 数据类型
    _Alignas (C keywords) – C 中文开发手册
    C 库函数 – modf()
    JavaScript E 属性
    SyntaxError.prototype (Errors) – JavaScript 中文开发手册
    swagger和openAPI: 上传文件
    Java中HashMap的putAll()方法: HashMap.putAll()
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6935038.html
Copyright © 2020-2023  润新知