#include <bits/stdc++.h>
#define DEBUG 0
using namespace std;
const int S = 524288, mod = 1000000007;
long long sc[S * 2][4];
long long query(int w, int p, int k, int pp, int kk, int tt)
{
if (DEBUG)
if (w == 1)
cout << "Z " << pp << ' ' << kk << ' ' << tt << ' ';
if (pp > k || kk < p)
{
if (DEBUG)
if (w == 1)
cout << " UU \n";
return 0;
}
if (pp <= p && kk >= k)
{
// cout << "W " << w << ' ' << p << ' ' << k << ' ' << sc[w][tt] << '\n';
return sc[w][tt];
if (DEBUG)
if (w == 1)
cout << " XX \n";
}
long long p1 = query(w * 2, p, (p + k) / 2, pp, kk, tt), p2 = query(w * 2 + 1, (p + k) / 2 + 1, k, pp, kk, tt);
if (w == 1)
{
if (DEBUG)
cout << p1 + p2 << '\n';
}
return (p1 + p2) % mod;
}
void setw(int w, long long wr, int tt)
{
w += S - 1;
while (w)
{
sc[w][tt] += wr;
sc[w][tt] %= mod;
w /= 2;
}
}
long long wr[300005];
int kop[300005];
long long dp[300005];
int main()
{
ios_base::sync_with_stdio(0);
int n;
cin >> n;
long long pref = 0;
vector<pair<long long, long long>> v;
for (int i = 1; i <= n; i++)
{
cin >> wr[i];
pref += wr[i];
v.push_back({pref % (mod), i});
}
if (n <= 3000)
{
dp[0] = 1;
for (int i = 1; i <= n; i++)
{
long long sm = 0, sw = 0;
for (int j = i; j; j--)
{
sm += wr[j];
sm %= mod;
if (!(sm % 2))
sw += dp[j - 1];
}
dp[i] = sw % mod;
}
cout << dp[n];
return 0;
}
sort(v.begin(), v.end());
int diff = 1, last = 0;
for (auto i : v)
{
if (i.first != last)
diff++;
last = i.first;
kop[i.second] = diff;
}
// for (int i = 1; i <= n; i++)
// {
// cout << kop[i] << ' ';
// }
// cout << '\n';
pref = 0;
long long lw = 0;
setw(1, 1, 0);
for (int i = 1; i <= n; i++)
{
pref += wr[i];
int ilop = (pref) % 2, ploi = (pref / (long long)(mod)) % 2;
if (DEBUG)
cout << ilop << ' ' << ploi << '\n';
long long mw = query(1, 1, S, 1, kop[i], 2 * ilop + ploi) + query(1, 1, S, kop[i] + 1, diff + 2, 2 * ilop + ploi ^ 1);
mw += query(1, 1, S, 1, kop[i], 2 * ilop + ploi ^ 3) + query(1, 1, S, kop[i] + 1, diff + 2, 2 * ilop + ploi ^ 2);
mw %= mod;
lw = mw;
if (DEBUG)
cout << i << ' ' << lw << '\n';
setw(kop[i], mw, 2 * ilop + ploi);
}
cout << lw;
}
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> #define DEBUG 0 using namespace std; const int S = 524288, mod = 1000000007; long long sc[S * 2][4]; long long query(int w, int p, int k, int pp, int kk, int tt) { if (DEBUG) if (w == 1) cout << "Z " << pp << ' ' << kk << ' ' << tt << ' '; if (pp > k || kk < p) { if (DEBUG) if (w == 1) cout << " UU \n"; return 0; } if (pp <= p && kk >= k) { // cout << "W " << w << ' ' << p << ' ' << k << ' ' << sc[w][tt] << '\n'; return sc[w][tt]; if (DEBUG) if (w == 1) cout << " XX \n"; } long long p1 = query(w * 2, p, (p + k) / 2, pp, kk, tt), p2 = query(w * 2 + 1, (p + k) / 2 + 1, k, pp, kk, tt); if (w == 1) { if (DEBUG) cout << p1 + p2 << '\n'; } return (p1 + p2) % mod; } void setw(int w, long long wr, int tt) { w += S - 1; while (w) { sc[w][tt] += wr; sc[w][tt] %= mod; w /= 2; } } long long wr[300005]; int kop[300005]; long long dp[300005]; int main() { ios_base::sync_with_stdio(0); int n; cin >> n; long long pref = 0; vector<pair<long long, long long>> v; for (int i = 1; i <= n; i++) { cin >> wr[i]; pref += wr[i]; v.push_back({pref % (mod), i}); } if (n <= 3000) { dp[0] = 1; for (int i = 1; i <= n; i++) { long long sm = 0, sw = 0; for (int j = i; j; j--) { sm += wr[j]; sm %= mod; if (!(sm % 2)) sw += dp[j - 1]; } dp[i] = sw % mod; } cout << dp[n]; return 0; } sort(v.begin(), v.end()); int diff = 1, last = 0; for (auto i : v) { if (i.first != last) diff++; last = i.first; kop[i.second] = diff; } // for (int i = 1; i <= n; i++) // { // cout << kop[i] << ' '; // } // cout << '\n'; pref = 0; long long lw = 0; setw(1, 1, 0); for (int i = 1; i <= n; i++) { pref += wr[i]; int ilop = (pref) % 2, ploi = (pref / (long long)(mod)) % 2; if (DEBUG) cout << ilop << ' ' << ploi << '\n'; long long mw = query(1, 1, S, 1, kop[i], 2 * ilop + ploi) + query(1, 1, S, kop[i] + 1, diff + 2, 2 * ilop + ploi ^ 1); mw += query(1, 1, S, 1, kop[i], 2 * ilop + ploi ^ 3) + query(1, 1, S, kop[i] + 1, diff + 2, 2 * ilop + ploi ^ 2); mw %= mod; lw = mw; if (DEBUG) cout << i << ' ' << lw << '\n'; setw(kop[i], mw, 2 * ilop + ploi); } cout << lw; } |
English