#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for (int i = (a); i <= (b); ++i)
#define REPD(i,a,b) for (int i = (a); i >= (b); --i)
#define FORI(i,n) REP(i,1,n)
#define FOR(i,n) REP(i,0,int(n)-1)
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define ll long long
#define SZ(x) int((x).size())
#define DBG(v) cerr << #v << " = " << (v) << endl;
#define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define fi first
#define se second
const int mod = 1000000007;
const int N = 300300;
//const int M = 1<<3;
const int M = 1<<19;
/// input
int n;
int a[N], pref[N], dp[N];
/// ids
pii prefs[N];
int ids[N];
int T[2][M*2+13];
void add(int t0, int pos, int val) {
//cerr << "adding (" << t0 << ") at position " << pos << " value " << val << "\n";
pos += M;
while (pos > 0) {
T[t0][pos] += val;
if (T[t0][pos] >= mod) T[t0][pos] -= mod;
pos /= 2;
}
/*cerr << "T[" << t0 << "] =";
FOR(i,M*2) {
if (__builtin_popcount(i) == 1) cerr << " |";
cerr << " " << T[t0][i];
}
cerr << "\n";*/
}
int get(int t0, int pos) {
//cerr << "reading (" << t0 << ") on interval [0, " << pos << "] : ";
pos += M;
int ans = T[t0][pos];
while (pos > 1) {
if ((pos & 1) == 1) {
ans += T[t0][pos-1];
if (ans >= mod) ans -= mod;
}
pos /= 2;
}
//cerr << ans << "\n";
return ans;
}
int main() {
/// read input
scanf("%d", &n);
FORI(i,n) scanf("%d", &a[i]);
FORI(i,n) pref[i] = (pref[i-1] + a[i]) % mod;
/// prepare ids
FOR(i,n+1) prefs[i] = mp(pref[i], i);
sort(prefs,prefs+n+1);
FOR(i,n+1) {
ids[prefs[i].se] = i;
if (i>0 && prefs[i].fi==prefs[i-1].fi) ids[prefs[i].se] = ids[prefs[i-1].se];
}
//FOR(i,n+1) cerr << "i = " << i << ", pref = " << pref[i] << ", id = " << ids[i] << "\n";
dp[0] = 1;
add(0, 0, 1);
FORI(i,n) {
/*int tmp_dp = 0;
FOR(j,i) {
if (pref[j] <= pref[i]) {
if (pref[i]%2 == pref[j]%2) tmp_dp += dp[j];
} else {
if (pref[i]%2 != pref[j]%2) tmp_dp += dp[j];
}
if (dp[i] >= mod) tmp_dp -= mod;
}*/
dp[i] = (0LL + get(pref[i]%2, ids[i]) + get(1-pref[i]%2, n) - get(1-pref[i]%2, ids[i]) + mod) % mod;
//cerr << "i = " << i << " : dp slow = " << tmp_dp << ", dp fast = " << dp[i] << "\n";
add(pref[i]%2, ids[i], dp[i]);
}
printf("%d\n", dp[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 | #include <bits/stdc++.h> using namespace std; #define REP(i,a,b) for (int i = (a); i <= (b); ++i) #define REPD(i,a,b) for (int i = (a); i >= (b); --i) #define FORI(i,n) REP(i,1,n) #define FOR(i,n) REP(i,0,int(n)-1) #define mp make_pair #define pb push_back #define pii pair<int,int> #define vi vector<int> #define ll long long #define SZ(x) int((x).size()) #define DBG(v) cerr << #v << " = " << (v) << endl; #define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++) #define fi first #define se second const int mod = 1000000007; const int N = 300300; //const int M = 1<<3; const int M = 1<<19; /// input int n; int a[N], pref[N], dp[N]; /// ids pii prefs[N]; int ids[N]; int T[2][M*2+13]; void add(int t0, int pos, int val) { //cerr << "adding (" << t0 << ") at position " << pos << " value " << val << "\n"; pos += M; while (pos > 0) { T[t0][pos] += val; if (T[t0][pos] >= mod) T[t0][pos] -= mod; pos /= 2; } /*cerr << "T[" << t0 << "] ="; FOR(i,M*2) { if (__builtin_popcount(i) == 1) cerr << " |"; cerr << " " << T[t0][i]; } cerr << "\n";*/ } int get(int t0, int pos) { //cerr << "reading (" << t0 << ") on interval [0, " << pos << "] : "; pos += M; int ans = T[t0][pos]; while (pos > 1) { if ((pos & 1) == 1) { ans += T[t0][pos-1]; if (ans >= mod) ans -= mod; } pos /= 2; } //cerr << ans << "\n"; return ans; } int main() { /// read input scanf("%d", &n); FORI(i,n) scanf("%d", &a[i]); FORI(i,n) pref[i] = (pref[i-1] + a[i]) % mod; /// prepare ids FOR(i,n+1) prefs[i] = mp(pref[i], i); sort(prefs,prefs+n+1); FOR(i,n+1) { ids[prefs[i].se] = i; if (i>0 && prefs[i].fi==prefs[i-1].fi) ids[prefs[i].se] = ids[prefs[i-1].se]; } //FOR(i,n+1) cerr << "i = " << i << ", pref = " << pref[i] << ", id = " << ids[i] << "\n"; dp[0] = 1; add(0, 0, 1); FORI(i,n) { /*int tmp_dp = 0; FOR(j,i) { if (pref[j] <= pref[i]) { if (pref[i]%2 == pref[j]%2) tmp_dp += dp[j]; } else { if (pref[i]%2 != pref[j]%2) tmp_dp += dp[j]; } if (dp[i] >= mod) tmp_dp -= mod; }*/ dp[i] = (0LL + get(pref[i]%2, ids[i]) + get(1-pref[i]%2, n) - get(1-pref[i]%2, ids[i]) + mod) % mod; //cerr << "i = " << i << " : dp slow = " << tmp_dp << ", dp fast = " << dp[i] << "\n"; add(pref[i]%2, ids[i], dp[i]); } printf("%d\n", dp[n]); return 0; } |
English