#include<cstdio> #include<cassert> #include<vector> typedef long long ll; #define PARDIF(a,b) ((sum[(a)]-sum[(b)]) %2) const ll MODULO = 1000000007; const int MAXN = 300000; #define NONE (MAXN+8) ll a[MAXN+10]; ll dp[MAXN+10][2]; ll sum[MAXN+10]; //int ind[MAXN+10]; int main() { std::vector<int> ind; int n, parz; dp[0][0] = 1; dp[0][1] = 0; dp[NONE][0] = 0; dp[NONE][1] = 0; sum[0] = 0; sum[NONE] = 0; scanf("%d", &n); ll spmod = 0, steps, lsteps; for (int i = 1; i <= n; ++i) { scanf("%lld", &a[i]); sum[i] = sum[i-1] + a[i]; parz = a[i] % 2; //printf("i=%d pi=%d parz=%d a=%lld sum=%lld\n", i, pi, parz, a[i], sum[i]); if (i == 1) { dp[i][0] = 0; dp[i][1] = 0; } else { dp[i][parz^1] = 0; dp[i][parz] = dp[i-1][0]; //printf("--\n"); //for (int k =0; k<2; ++k){ // for(int i=0; i<=n;++i) { // printf("%lld ", dp[i][k]); // } // putchar('\n'); //} //dp[i][parz] = (dp[i-1][0] - dp[pi][PARDIF(i-1,pi)] /*+ dp[i-1][1] - dp[i-1][1]*/ + dp[pi][PARDIF(i-1,pi)^1] + MODULO) % MODULO; for (int j = 0, sgn=0; j<ind.size(); ++j, sgn ^= 1) { dp[i][parz] += (- dp[ind[j]][PARDIF(i-1,ind[j])^sgn] /*+ dp[i-1][1] - dp[i-1][1]*/ + dp[ind[j]][PARDIF(i-1,ind[j])^1^sgn] + MODULO) % MODULO; } dp[i][parz] %= MODULO; //for (int k =0; k<2; ++k){ // for(int i=0; i<=n;++i) { // printf("%lld ", dp[i][k]); // } // putchar('\n'); //} } //printf("dp[i][0]_1=%lld dp[i][1]_1=%lld\n", dp[i][0], dp[i][1]); dp[i][1] += dp[i-1][1^parz]; dp[i][1] %= MODULO; dp[i][0] += dp[i-1][0^parz]; dp[i][0] %= MODULO; //printf("dp[i][0]_2=%lld dp[i][1]_2=%lld\n", dp[i][0], dp[i][1]); //+= steps = sum[i] / MODULO; if (steps != spmod){ ind.push_back(0); spmod = steps; } assert(steps == ind.size()); lsteps = 0; for (auto it = ind.begin(), end=ind.end(); it != end; ++it) { lsteps += MODULO; while ( sum[i] - sum[*it] >= lsteps ) ++(*it); *it = *it == 0? NONE : (*it); } //pi = ind[i-1]; } ll wyn = dp[n][0]; //printf("%lld\n", wyn); for (int j = 0, sgn=0; j<ind.size(); ++j, sgn ^= 1) { wyn += (- dp[ind[j]][PARDIF(n,ind[j])^sgn] /*+ dp[i-1][1] - dp[i-1][1]*/ + dp[ind[j]][PARDIF(n,ind[j])^1^sgn] + MODULO) % MODULO; //printf("po j=%d %lld\n", j, wyn); } wyn %= MODULO; printf("%lld\n", wyn); //for (int k =0; k<2; ++k){ // for(int i=0; i<=n;++i) { // printf("%lld ", dp[i][k]); // } // putchar('\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 | #include<cstdio> #include<cassert> #include<vector> typedef long long ll; #define PARDIF(a,b) ((sum[(a)]-sum[(b)]) %2) const ll MODULO = 1000000007; const int MAXN = 300000; #define NONE (MAXN+8) ll a[MAXN+10]; ll dp[MAXN+10][2]; ll sum[MAXN+10]; //int ind[MAXN+10]; int main() { std::vector<int> ind; int n, parz; dp[0][0] = 1; dp[0][1] = 0; dp[NONE][0] = 0; dp[NONE][1] = 0; sum[0] = 0; sum[NONE] = 0; scanf("%d", &n); ll spmod = 0, steps, lsteps; for (int i = 1; i <= n; ++i) { scanf("%lld", &a[i]); sum[i] = sum[i-1] + a[i]; parz = a[i] % 2; //printf("i=%d pi=%d parz=%d a=%lld sum=%lld\n", i, pi, parz, a[i], sum[i]); if (i == 1) { dp[i][0] = 0; dp[i][1] = 0; } else { dp[i][parz^1] = 0; dp[i][parz] = dp[i-1][0]; //printf("--\n"); //for (int k =0; k<2; ++k){ // for(int i=0; i<=n;++i) { // printf("%lld ", dp[i][k]); // } // putchar('\n'); //} //dp[i][parz] = (dp[i-1][0] - dp[pi][PARDIF(i-1,pi)] /*+ dp[i-1][1] - dp[i-1][1]*/ + dp[pi][PARDIF(i-1,pi)^1] + MODULO) % MODULO; for (int j = 0, sgn=0; j<ind.size(); ++j, sgn ^= 1) { dp[i][parz] += (- dp[ind[j]][PARDIF(i-1,ind[j])^sgn] /*+ dp[i-1][1] - dp[i-1][1]*/ + dp[ind[j]][PARDIF(i-1,ind[j])^1^sgn] + MODULO) % MODULO; } dp[i][parz] %= MODULO; //for (int k =0; k<2; ++k){ // for(int i=0; i<=n;++i) { // printf("%lld ", dp[i][k]); // } // putchar('\n'); //} } //printf("dp[i][0]_1=%lld dp[i][1]_1=%lld\n", dp[i][0], dp[i][1]); dp[i][1] += dp[i-1][1^parz]; dp[i][1] %= MODULO; dp[i][0] += dp[i-1][0^parz]; dp[i][0] %= MODULO; //printf("dp[i][0]_2=%lld dp[i][1]_2=%lld\n", dp[i][0], dp[i][1]); //+= steps = sum[i] / MODULO; if (steps != spmod){ ind.push_back(0); spmod = steps; } assert(steps == ind.size()); lsteps = 0; for (auto it = ind.begin(), end=ind.end(); it != end; ++it) { lsteps += MODULO; while ( sum[i] - sum[*it] >= lsteps ) ++(*it); *it = *it == 0? NONE : (*it); } //pi = ind[i-1]; } ll wyn = dp[n][0]; //printf("%lld\n", wyn); for (int j = 0, sgn=0; j<ind.size(); ++j, sgn ^= 1) { wyn += (- dp[ind[j]][PARDIF(n,ind[j])^sgn] /*+ dp[i-1][1] - dp[i-1][1]*/ + dp[ind[j]][PARDIF(n,ind[j])^1^sgn] + MODULO) % MODULO; //printf("po j=%d %lld\n", j, wyn); } wyn %= MODULO; printf("%lld\n", wyn); //for (int k =0; k<2; ++k){ // for(int i=0; i<=n;++i) { // printf("%lld ", dp[i][k]); // } // putchar('\n'); //} return 0; } |