• [51NOD1065] 最小正子段和(STL,前缀和)


    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1065

    估计没人这么做吧…用一个set维护前缀和,但是set的lower_bound和upper_bound都是返回不小于x的最小值,这就很尴尬了。

     重载了这个<,在树里面前序遍历出来的就是降序了。 然后二分的时候还是用的这个<,原本意思是找到不小于的第一个,但是重载以后,查找的位置不变,结果就是不大于的了。
     1 #include <bits/stdc++.h>
     2 #include<ext/pb_ds/assoc_container.hpp>
     3 using namespace std;
     4 using namespace __gnu_pbds;
     5 
     6 typedef long long LL;
     7 typedef struct F {
     8   LL v;
     9   F() {}
    10   F(LL v) : v(v) {}
    11   bool operator<(const F &x) const {
    12     return v > x.v;
    13   }
    14 }F;
    15 const int maxn = 50050 * 2;
    16 int n;
    17 int a[maxn];
    18 LL s[maxn];
    19 set<F> v;
    20 
    21 int main() {
    22   //freopen("in", "r", stdin);
    23   while(~scanf("%d", &n)) {
    24     memset(s, 0, sizeof(s));
    25     v.clear(); v.insert(s[0]);
    26     LL ret = (LL)1 << 60;
    27     for(int i = 1; i <= n; i++) {
    28       scanf("%d", &a[i]);
    29       s[i] = s[i-1] + a[i];
    30       if(a[i] >= 1) ret = min(ret, (LL)a[i]);
    31       if(s[i] >= 1) ret = min(ret, s[i]);
    32       F tmp = *v.lower_bound(s[i]);
    33       if(s[i] - tmp.v >= 1) {
    34         ret = min(ret, s[i]-tmp.v);
    35       }
    36       v.insert(F(s[i]));
    37     }
    38     cout << ret << endl;
    39   }
    40   return 0;
    41 }

    噗,直接在set后面加一个greater就好。。

     1 #include <bits/stdc++.h>
     2 #include<ext/pb_ds/assoc_container.hpp>
     3 using namespace std;
     4 using namespace __gnu_pbds;
     5 
     6 typedef long long LL;
     7 const int maxn = 50050 * 2;
     8 int n;
     9 int a[maxn];
    10 LL s[maxn];
    11 set<LL, greater<LL> > v;
    12 
    13 int main() {
    14   //freopen("in", "r", stdin);
    15   while(~scanf("%d", &n)) {
    16     memset(s, 0, sizeof(s));
    17     v.clear(); v.insert(s[0]);
    18     LL ret = (LL)1 << 60;
    19     for(int i = 1; i <= n; i++) {
    20       scanf("%d", &a[i]);
    21       s[i] = s[i-1] + a[i];
    22       if(a[i] >= 1) ret = min(ret, (LL)a[i]);
    23       if(s[i] >= 1) ret = min(ret, s[i]);
    24       LL tmp = *v.upper_bound(s[i]);
    25       if(s[i]-tmp >= 1) {
    26         ret = min(ret, s[i]-tmp);
    27       }
    28       v.insert(s[i]);
    29     }
    30     cout << ret << endl;
    31   }
    32   return 0;
    33 }
  • 相关阅读:
    java里如何使用输入流和输出流实现读取本地文件里内容和写出到本地文件里
    Windows 命令行基础(博主推荐)
    Python2.7编程基础(博主推荐)
    27 个Jupyter Notebook的小提示与技巧
    java里如何实现循环打印出字符或字符数组里的内容
    [转]angularjs之ui-grid 使用详解
    [转]AngularJS 实现 Table的一些操作(示例大于实际)
    [转]js 回车转成TAB(利用tabindex)
    [转] Entity Framework添加记录时获取自增ID值
    [转]使用依赖关系注入在 ASP.NET Core 中编写干净代码
  • 原文地址:https://www.cnblogs.com/kirai/p/5994477.html
Copyright © 2020-2023  润新知