#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#ifdef LOCAL
#define debug(...) __VA_ARGS__
#else
#define debug(...) {}
#endif
ll dp[5001][5001];
const int base = (1<<19);
int base2 = base-1;
ll tree[2*base];
void change(int a, int b, ll x){
a += base-1;
b += base+1;
while (b-a > 1){
if (!(a%2)) tree[a+1] += x;
if (b%2) tree[b-1] += x;
a /= 2;
b /= 2;
}
}
ll query(int v){
v += base;
ll wy = 0;
while (v){
wy += tree[v];
v /= 2;
}
return wy;
}
int query2(int v){
int p = v;
int k = base2;
int s;
while (p < k){
s = (p+k)/2;
if (query(s) < 0) p = s+1;
else k = s;
}
s = (p+k)/2;
if (query(s) >= 0) return s;
else return -1;
}
const ll INF = -2137213721372137;
int main(){
ios_base::sync_with_stdio(0);
cin.tie();
cout.tie();
debug(freopen("ele0.in","r",stdin););
int i;
int n;
cin>>n;
if (n > 5000){
int fakewy = 0;
int pointer = 0;
ll akt;
cin>>akt;
tree[base2+base] = akt;
for (i = 1; i < n; i++){
cin>>akt;
int s = query2(base2-pointer);
bool fr = 0;
if (query(base2-pointer) >= 0){
pointer++;
fr = 1;
}
else fakewy++;
change(base2-pointer,base,akt);
if (s != -1 && !fr){
//cout<<s<<"\n";
//cout<<s-moved<<" "<<query(s-moved)<<" "<<akt<<"\n";
if (query(s-1) < akt){
tree[s+base-1] += akt-query(s-1);
}
}
//cout<<fakewy<<" # ";
//for (int j = base2-pointer; j < base2+1; j++) cout<<query(j)<<" ";
//cout<<"\n";
//return 0;
}
for (i = base2-pointer; i < base2+1; i++){
if (query(i) >= 0){
cout<<fakewy+(i-base2+pointer)<<"\n";
return 0;
}
}
cout<<-1<<"\n";
return 0;
}
for (i = 0; i < n ; i++) dp[1][i] = INF;
ll akt;
cin>>akt;
dp[1][0] = akt;
for (i = 2; i < n+1; i++){
cin>>akt;
if (dp[i-1][0] >= 0) dp[i][0] = akt;
else dp[i][0] = INF;
for (int j = 1; j < n; j++){
dp[i][j] = dp[i-1][j-1]+akt;
if (dp[i-1][j] >= 0) dp[i][j] = max(dp[i][j],akt);
dp[i][j] = max(dp[i][j],INF);
//cout<<i<<" "<<j<<" "<<dp[i][j]<<"\n";
}
}
for (i = 0; i < n; i++){
if (dp[n][i] >= 0){
cout<<i<<"\n";
return 0;
}
}
cout<<-1<<"\n";
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #include <bits/stdc++.h> using namespace std; typedef long long ll; #ifdef LOCAL #define debug(...) __VA_ARGS__ #else #define debug(...) {} #endif ll dp[5001][5001]; const int base = (1<<19); int base2 = base-1; ll tree[2*base]; void change(int a, int b, ll x){ a += base-1; b += base+1; while (b-a > 1){ if (!(a%2)) tree[a+1] += x; if (b%2) tree[b-1] += x; a /= 2; b /= 2; } } ll query(int v){ v += base; ll wy = 0; while (v){ wy += tree[v]; v /= 2; } return wy; } int query2(int v){ int p = v; int k = base2; int s; while (p < k){ s = (p+k)/2; if (query(s) < 0) p = s+1; else k = s; } s = (p+k)/2; if (query(s) >= 0) return s; else return -1; } const ll INF = -2137213721372137; int main(){ ios_base::sync_with_stdio(0); cin.tie(); cout.tie(); debug(freopen("ele0.in","r",stdin);); int i; int n; cin>>n; if (n > 5000){ int fakewy = 0; int pointer = 0; ll akt; cin>>akt; tree[base2+base] = akt; for (i = 1; i < n; i++){ cin>>akt; int s = query2(base2-pointer); bool fr = 0; if (query(base2-pointer) >= 0){ pointer++; fr = 1; } else fakewy++; change(base2-pointer,base,akt); if (s != -1 && !fr){ //cout<<s<<"\n"; //cout<<s-moved<<" "<<query(s-moved)<<" "<<akt<<"\n"; if (query(s-1) < akt){ tree[s+base-1] += akt-query(s-1); } } //cout<<fakewy<<" # "; //for (int j = base2-pointer; j < base2+1; j++) cout<<query(j)<<" "; //cout<<"\n"; //return 0; } for (i = base2-pointer; i < base2+1; i++){ if (query(i) >= 0){ cout<<fakewy+(i-base2+pointer)<<"\n"; return 0; } } cout<<-1<<"\n"; return 0; } for (i = 0; i < n ; i++) dp[1][i] = INF; ll akt; cin>>akt; dp[1][0] = akt; for (i = 2; i < n+1; i++){ cin>>akt; if (dp[i-1][0] >= 0) dp[i][0] = akt; else dp[i][0] = INF; for (int j = 1; j < n; j++){ dp[i][j] = dp[i-1][j-1]+akt; if (dp[i-1][j] >= 0) dp[i][j] = max(dp[i][j],akt); dp[i][j] = max(dp[i][j],INF); //cout<<i<<" "<<j<<" "<<dp[i][j]<<"\n"; } } for (i = 0; i < n; i++){ if (dp[n][i] >= 0){ cout<<i<<"\n"; return 0; } } cout<<-1<<"\n"; return 0; } |
English