zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
    
  • 相关阅读:
    Windows删除被占用的文件或文件夹
    Fatal error in launcher: Unable to create process using
    World/excel无法同时打开两个解决办法
    Zabbix故障处理系列
    第1章 数据库系统概述
    第2章 关系数据库
    第3章 数据库设计
    Linux命令概况
    Python -扩展C++-Pytorch扩展
    技术栈_人工智能-大数据-云计算
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6935038.html
Copyright © 2011-2022 走看看