#include <bits/stdc++.h> using namespace std; const int mod = 1000 * 1000 * 1000 + 7; struct drz { drz *l; drz *p; long long int v; drz() { l = NULL; p = NULL; v = 1; } long long lew() { if (l == NULL) return 0; return l -> v; } long long pra() { if (p == NULL) return 0; return p -> v; } }; drz * root; void dodaj_nowy_korzen () { drz *r = root; root = new drz(); root -> l = r; root -> p = r; root -> v = (root -> lew() + root -> pra()) % mod; } const int N = 1000 * 1000 + 5; vector< vector<pair<int,bool> > > wyrazenia; vector<pair<int,bool> > empty; drz* wstaw(const vector<pair<int,bool> >& z, int id, drz* v) { drz* result = new drz(); result -> l = v -> l; result -> p = v -> p; if (v -> v == 0 || id == (int)z.size()) { result -> v = 0; } else { if (z[id].second) { result -> l = wstaw(z, id+1, v -> l); } else { result -> p = wstaw(z, id+1, v -> p); } result -> v = (result -> lew() + result -> pra()) % mod; } return result; } const int BUF_SIZE = 1000 * 1000 * 20; char bufor[BUF_SIZE]; bool jest_cyfra(char x) { return x <= '9' && x >= '0'; } int main() { int n; scanf("%d\n", &n); fgets(bufor, BUF_SIZE, stdin); int size = strlen(bufor); int beg = 0; while(beg < size) { bool znak = true; if (bufor[beg] == '(') { wyrazenia.push_back(empty); } if (bufor[beg] == '~') { beg ++; znak = false; } if (bufor[beg] == 'x') { beg ++; int numer_zmiennej = 0; while(jest_cyfra(bufor[beg])) { numer_zmiennej *= 10; numer_zmiennej += bufor[beg] - '0'; beg ++; } wyrazenia.back().push_back(make_pair(numer_zmiennej, znak)); beg --; } beg ++; } for (auto &v: wyrazenia) { sort(v.begin(), v.end()); } sort(wyrazenia.begin(), wyrazenia.end(), [](const vector<pair<int, bool> >& a, const vector<pair<int, bool> >& b) { return a[0] < b[0]; }); root = new drz(); // printf("wyrazen %d\n", wyrazenia.size()); // for (auto v: wyrazenia) { // for (auto x: v) { // printf("%d %d, ", x.first, x.second); // } // printf("\n"); // } int id = wyrazenia.size() - 1; for (int x = n; x >= 1; x --) { dodaj_nowy_korzen(); // printf("%d -- %lld\n", x, root->v); // printf("szukaj wyrazenia %d\n", wyrazenia[id][0].first); while (id >= 0 && wyrazenia[id][0].first == x) { root = wstaw(wyrazenia[id], 0, root); // printf("inside %d -- %lld\n", x, root->v); id --; } // printf("%d -- %lld\n", x, root->v); } printf("%lld\n", root -> v); }
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 | #include <bits/stdc++.h> using namespace std; const int mod = 1000 * 1000 * 1000 + 7; struct drz { drz *l; drz *p; long long int v; drz() { l = NULL; p = NULL; v = 1; } long long lew() { if (l == NULL) return 0; return l -> v; } long long pra() { if (p == NULL) return 0; return p -> v; } }; drz * root; void dodaj_nowy_korzen () { drz *r = root; root = new drz(); root -> l = r; root -> p = r; root -> v = (root -> lew() + root -> pra()) % mod; } const int N = 1000 * 1000 + 5; vector< vector<pair<int,bool> > > wyrazenia; vector<pair<int,bool> > empty; drz* wstaw(const vector<pair<int,bool> >& z, int id, drz* v) { drz* result = new drz(); result -> l = v -> l; result -> p = v -> p; if (v -> v == 0 || id == (int)z.size()) { result -> v = 0; } else { if (z[id].second) { result -> l = wstaw(z, id+1, v -> l); } else { result -> p = wstaw(z, id+1, v -> p); } result -> v = (result -> lew() + result -> pra()) % mod; } return result; } const int BUF_SIZE = 1000 * 1000 * 20; char bufor[BUF_SIZE]; bool jest_cyfra(char x) { return x <= '9' && x >= '0'; } int main() { int n; scanf("%d\n", &n); fgets(bufor, BUF_SIZE, stdin); int size = strlen(bufor); int beg = 0; while(beg < size) { bool znak = true; if (bufor[beg] == '(') { wyrazenia.push_back(empty); } if (bufor[beg] == '~') { beg ++; znak = false; } if (bufor[beg] == 'x') { beg ++; int numer_zmiennej = 0; while(jest_cyfra(bufor[beg])) { numer_zmiennej *= 10; numer_zmiennej += bufor[beg] - '0'; beg ++; } wyrazenia.back().push_back(make_pair(numer_zmiennej, znak)); beg --; } beg ++; } for (auto &v: wyrazenia) { sort(v.begin(), v.end()); } sort(wyrazenia.begin(), wyrazenia.end(), [](const vector<pair<int, bool> >& a, const vector<pair<int, bool> >& b) { return a[0] < b[0]; }); root = new drz(); // printf("wyrazen %d\n", wyrazenia.size()); // for (auto v: wyrazenia) { // for (auto x: v) { // printf("%d %d, ", x.first, x.second); // } // printf("\n"); // } int id = wyrazenia.size() - 1; for (int x = n; x >= 1; x --) { dodaj_nowy_korzen(); // printf("%d -- %lld\n", x, root->v); // printf("szukaj wyrazenia %d\n", wyrazenia[id][0].first); while (id >= 0 && wyrazenia[id][0].first == x) { root = wstaw(wyrazenia[id], 0, root); // printf("inside %d -- %lld\n", x, root->v); id --; } // printf("%d -- %lld\n", x, root->v); } printf("%lld\n", root -> v); } |