题目链接: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 }