#include <bits/stdc++.h> #define REP(i,n) for (int _n=(n), i=0;i<_n;++i) #define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;++i) #define FORD(i,a,b) for (int i=(a),_b=(b);i>=_b;--i) #define TRACE(x) std::cerr << "TRACE(" #x ")" << std::endl; #define DEBUG(x) std::cerr << #x << " = " << (x) << std::endl; void init_io() { std::cin.tie(nullptr); std::ios::sync_with_stdio(false); } template<unsigned MOD> class Modulo { public: Modulo(unsigned x=0):v(x) {} unsigned get() const { return v; } Modulo operator+(Modulo b) const { unsigned res = v+b.v; if (res >= MOD) res -= MOD; return Modulo(res); } void operator+=(Modulo b) { *this = *this + b; } Modulo operator-(Modulo b) const { return *this + Modulo(MOD-b.v); } void operator-=(Modulo b) { *this = *this - b; } Modulo operator*(Modulo b) const { return Modulo(std::uint64_t(v) * b.v % MOD); } void operator*=(Modulo b) { *this = *this * b; } bool operator==(Modulo b) const { return v == b.v; } bool operator!=(Modulo b) const { return v != b.v; } bool operator<(Modulo b) const { return v < b.v; } bool operator>(Modulo b) const { return v > b.v; } bool operator<=(Modulo b) const { return v <= b.v; } bool operator>=(Modulo b) const { return v >= b.v; } private: unsigned v; }; template<class T> class Fenwick { public: explicit Fenwick(int n): tab(n+1) {} void Add(int p, const T &v); T Sum(int n) const; T SumAll() const { return sum_all; } private: std::vector<T> tab; T sum_all{}; }; template<class T> void Fenwick<T>::Add(int p, const T &v) { ++p; while(p < static_cast<int>(tab.size())) { tab[p] += v; p += (p & -p); } sum_all += v; } template<class T> T Fenwick<T>::Sum(int n) const { T res = T(); while(n) { res += tab[n]; n &= (n-1); } return res; } using Mod = Modulo<1'000'000'007>; std::vector<Mod> prefix_sums; std::vector<Mod> unique_sums; void read_prefix_sums() { int n; std::cin >> n; prefix_sums.reserve(n + 1); Mod sum {0}; prefix_sums.push_back(sum); REP(i, n) { unsigned v; std::cin >> v; sum += Mod(v); prefix_sums.push_back(sum); } } void calc_unique_sums() { unique_sums = prefix_sums; std::sort(unique_sums.begin(), unique_sums.end()); const auto it = std::unique(unique_sums.begin(), unique_sums.end()); unique_sums.erase(it, unique_sums.end()); } int find_index(const Mod x) { const auto it = std::lower_bound(unique_sums.begin(), unique_sums.end(), x); assert(it != unique_sums.end()); assert(*it == x); return it - unique_sums.begin(); } struct Elem { Mod ways[2] = {}; void operator+=(const Elem &b) { ways[0] += b.ways[0]; ways[1] += b.ways[1]; } }; Mod solve() { Fenwick<Elem> ways_table { int(unique_sums.size()) }; Mod res{1}; { Elem elem; elem.ways[0] = res; ways_table.Add(find_index(Mod(0)), elem); } for (auto it = prefix_sums.begin() + 1; it != prefix_sums.end(); ++it) { const Mod x = *it; const int index = find_index(x); const Elem small = ways_table.Sum(index+1); const Elem all = ways_table.SumAll(); const unsigned parity = x.get() & 1; res = small.ways[parity] + all.ways[parity ^ 1] - small.ways[parity ^ 1]; Elem new_elem; new_elem.ways[parity] = res; ways_table.Add(index, new_elem); } return res; } int main() { init_io(); read_prefix_sums(); calc_unique_sums(); const Mod res = solve(); std::cout << res.get() << '\n'; }
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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | #include <bits/stdc++.h> #define REP(i,n) for (int _n=(n), i=0;i<_n;++i) #define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;++i) #define FORD(i,a,b) for (int i=(a),_b=(b);i>=_b;--i) #define TRACE(x) std::cerr << "TRACE(" #x ")" << std::endl; #define DEBUG(x) std::cerr << #x << " = " << (x) << std::endl; void init_io() { std::cin.tie(nullptr); std::ios::sync_with_stdio(false); } template<unsigned MOD> class Modulo { public: Modulo(unsigned x=0):v(x) {} unsigned get() const { return v; } Modulo operator+(Modulo b) const { unsigned res = v+b.v; if (res >= MOD) res -= MOD; return Modulo(res); } void operator+=(Modulo b) { *this = *this + b; } Modulo operator-(Modulo b) const { return *this + Modulo(MOD-b.v); } void operator-=(Modulo b) { *this = *this - b; } Modulo operator*(Modulo b) const { return Modulo(std::uint64_t(v) * b.v % MOD); } void operator*=(Modulo b) { *this = *this * b; } bool operator==(Modulo b) const { return v == b.v; } bool operator!=(Modulo b) const { return v != b.v; } bool operator<(Modulo b) const { return v < b.v; } bool operator>(Modulo b) const { return v > b.v; } bool operator<=(Modulo b) const { return v <= b.v; } bool operator>=(Modulo b) const { return v >= b.v; } private: unsigned v; }; template<class T> class Fenwick { public: explicit Fenwick(int n): tab(n+1) {} void Add(int p, const T &v); T Sum(int n) const; T SumAll() const { return sum_all; } private: std::vector<T> tab; T sum_all{}; }; template<class T> void Fenwick<T>::Add(int p, const T &v) { ++p; while(p < static_cast<int>(tab.size())) { tab[p] += v; p += (p & -p); } sum_all += v; } template<class T> T Fenwick<T>::Sum(int n) const { T res = T(); while(n) { res += tab[n]; n &= (n-1); } return res; } using Mod = Modulo<1'000'000'007>; std::vector<Mod> prefix_sums; std::vector<Mod> unique_sums; void read_prefix_sums() { int n; std::cin >> n; prefix_sums.reserve(n + 1); Mod sum {0}; prefix_sums.push_back(sum); REP(i, n) { unsigned v; std::cin >> v; sum += Mod(v); prefix_sums.push_back(sum); } } void calc_unique_sums() { unique_sums = prefix_sums; std::sort(unique_sums.begin(), unique_sums.end()); const auto it = std::unique(unique_sums.begin(), unique_sums.end()); unique_sums.erase(it, unique_sums.end()); } int find_index(const Mod x) { const auto it = std::lower_bound(unique_sums.begin(), unique_sums.end(), x); assert(it != unique_sums.end()); assert(*it == x); return it - unique_sums.begin(); } struct Elem { Mod ways[2] = {}; void operator+=(const Elem &b) { ways[0] += b.ways[0]; ways[1] += b.ways[1]; } }; Mod solve() { Fenwick<Elem> ways_table { int(unique_sums.size()) }; Mod res{1}; { Elem elem; elem.ways[0] = res; ways_table.Add(find_index(Mod(0)), elem); } for (auto it = prefix_sums.begin() + 1; it != prefix_sums.end(); ++it) { const Mod x = *it; const int index = find_index(x); const Elem small = ways_table.Sum(index+1); const Elem all = ways_table.SumAll(); const unsigned parity = x.get() & 1; res = small.ways[parity] + all.ways[parity ^ 1] - small.ways[parity ^ 1]; Elem new_elem; new_elem.ways[parity] = res; ways_table.Add(index, new_elem); } return res; } int main() { init_io(); read_prefix_sums(); calc_unique_sums(); const Mod res = solve(); std::cout << res.get() << '\n'; } |