Niestety, nie byliśmy w stanie w pełni poprawnie wyświetlić tego pliku, ponieważ nie jest zakodowany w UTF-8.
Możesz pobrać ten plik i spróbować otworzyć go samodzielnie.
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
long long tab[300007];
long long ile[300007];
const long long M = 1000000007;
long long roznice[300007];
map <long long, int> pskal; // skalowanie parzystych r�nic
map <long long, int> nskal; // skalowanie nieparzystych r�nic
long long niep[1048587]; // drzewo nieparzystych
long long parz[1048587]; // drzewo parzystych
void dodaj(long long* drzewo, int i, long long wart) {
//cout<<"dodaj "<<i<<" "<<wart<<endl;
drzewo[i] = (drzewo[i] + wart) % M;
//cout<<"drzewo["<<i<<"] = "<<drzewo[i]<<endl;
i /= 2;
while (i > 0) {
drzewo[i] = (drzewo[2 * i] + drzewo[2 * i + 1]) % M;
//cout<<"drzewo["<<i<<"] = "<<drzewo[i]<<endl;
i /= 2;
}
}
long long czytaj(long long* drzewo, int ojc, int a, int b, int pocz, int kon) { // zwraca sum� przedzia�u pocz-kon
//cout<<"czytaj: ojc = "<<ojc<<" a = "<<a<<" b = "<<b<<" pocz = "<<pocz<<" kon = "<<kon<<endl;
if (a > kon || b < pocz) {
return 0;
}
if (a >= pocz && b <= kon) {
//cout<<"zwracam "<<drzewo[ojc]<<endl;
return drzewo[ojc];
}
return (czytaj(drzewo, 2 * ojc, a, (a + b) / 2, pocz, kon) + czytaj(drzewo, 2 * ojc + 1, (a + b) / 2 + 1, b, pocz, kon)) % M;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int n;
cin>>n;
for (int i = 0; i < n; i++) {
cin>>tab[i];
if (i > 0) {
tab[i] = (tab[i] + tab[i - 1]) % M;
}
roznice[i] = tab[i];
}
// skalowanie
sort(roznice, roznice + n);
for (int i = 0; i < n; i++) {
if (i == 0 || roznice[i] != roznice[i - 1]) {
if (roznice[i] % 2 == 0)
pskal.insert({roznice[i], pskal.size()});
else
nskal.insert({roznice[i], nskal.size()});
}
}
int mparz = 1; // rozmiar drzewa dla parzystych
while (mparz < pskal.size()) mparz *= 2;
//cout<<"mparz = "<<mparz<<endl;
int mniep = 1; // rozmiar drzewa dla nieparzystych
while (mniep < nskal.size()) mniep *= 2;
//cout<<"mniep = "<<mniep<<endl;
for (int i = 0; i < n; i++) {
if (tab[i] % 2 == 0) {
ile[i] = 1;
// bierzemy parzyste mniejsze r�wne
//cout<<"parzyste <= "<<tab[i]<<endl;
map<long long, int>::iterator it = pskal.upper_bound(tab[i]); // pierwszy wi�kszy parzysty (lub end je�li nie ma)
int kon = (it == pskal.end()) ? kon = pskal.size() - 1 : it->second - 1;
ile[i] += czytaj(parz, 1, mparz, 2 * mparz - 1, mparz, kon + mparz);
ile[i] %= M;
// bierzemy nieparzyste wi�ksze
//cout<<"nieparzyste > "<<tab[i]<<endl;
it = nskal.upper_bound(tab[i]); // pierwszy wi�kszy nieparzysty (lub end je�li nie ma)
if (it != nskal.end()) { // je�li w og�le jest jaki� nieparzysty
int pocz = it->second;
ile[i] += czytaj(niep, 1, mniep, 2 * mniep - 1, pocz + mniep, 2 * mniep - 1);
ile[i] %= M;
}
dodaj(parz, pskal[tab[i]] + mparz, ile[i]);
}
else {
// bierzemy nieparzyste mniejsze r�wne
//cout<<"nieparzyste <= "<<tab[i]<<endl;
map<long long, int>::iterator it = nskal.upper_bound(tab[i]); // pierwszy wi�kszy nieparzysty (lub end je�li nie ma)
int kon = (it == nskal.end()) ? nskal.size() - 1 : it->second - 1;
ile[i] += czytaj(niep, 1, mniep, 2 * mniep - 1, mniep, kon + mniep);
ile[i] %= M;
// bierzemy parzyste wi�ksze
//cout<<"parzyste > "<<tab[i]<<endl;
//cout<<"tab["<<i<<"] = "<<tab[i]<<endl;
it = pskal.upper_bound(tab[i]);
if (it != pskal.end()) {
int pocz = it->second;
ile[i] += czytaj(parz, 1, mparz, 2 * mparz - 1, pocz + mparz, 2 * mparz - 1);
ile[i] %= M;
}
dodaj(niep, nskal[tab[i]] + mniep, ile[i]);
}
//cout<<i<<" "<<tab[i]<<endl;
/*
if (tab[i] % 2 == 0) ile2[i] = 1;
for (int j = 0; j < i; j++) {
if (tab[j] <= tab[i] && tab[j] % 2 == tab[i] % 2) {
ile2[i] += ile2[j];
ile2[i] %= M;
//cout<<"przdluzam mniejsze tej samej parzysto�ci "<<j<<" "<<tab[j]<<" do "<<ile2[i]<<endl;
}
else if (tab[j] > tab[i] && tab[j] % 2 != tab[i] % 2) {
ile2[i] += ile2[j];
ile2[i] %= M;
//cout<<"przdluzam wieksze innej parzystosci "<<j<<" "<<tab[j]<<" do "<<ile2[i]<<endl;
}
}
if (ile[i] != ile2[i]) break;
*/
}
cout<<ile[n - 1]<<"\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 | #include <iostream> #include <algorithm> #include <map> using namespace std; long long tab[300007]; long long ile[300007]; const long long M = 1000000007; long long roznice[300007]; map <long long, int> pskal; // skalowanie parzystych r�nic map <long long, int> nskal; // skalowanie nieparzystych r�nic long long niep[1048587]; // drzewo nieparzystych long long parz[1048587]; // drzewo parzystych void dodaj(long long* drzewo, int i, long long wart) { //cout<<"dodaj "<<i<<" "<<wart<<endl; drzewo[i] = (drzewo[i] + wart) % M; //cout<<"drzewo["<<i<<"] = "<<drzewo[i]<<endl; i /= 2; while (i > 0) { drzewo[i] = (drzewo[2 * i] + drzewo[2 * i + 1]) % M; //cout<<"drzewo["<<i<<"] = "<<drzewo[i]<<endl; i /= 2; } } long long czytaj(long long* drzewo, int ojc, int a, int b, int pocz, int kon) { // zwraca sum� przedzia�u pocz-kon //cout<<"czytaj: ojc = "<<ojc<<" a = "<<a<<" b = "<<b<<" pocz = "<<pocz<<" kon = "<<kon<<endl; if (a > kon || b < pocz) { return 0; } if (a >= pocz && b <= kon) { //cout<<"zwracam "<<drzewo[ojc]<<endl; return drzewo[ojc]; } return (czytaj(drzewo, 2 * ojc, a, (a + b) / 2, pocz, kon) + czytaj(drzewo, 2 * ojc + 1, (a + b) / 2 + 1, b, pocz, kon)) % M; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n; cin>>n; for (int i = 0; i < n; i++) { cin>>tab[i]; if (i > 0) { tab[i] = (tab[i] + tab[i - 1]) % M; } roznice[i] = tab[i]; } // skalowanie sort(roznice, roznice + n); for (int i = 0; i < n; i++) { if (i == 0 || roznice[i] != roznice[i - 1]) { if (roznice[i] % 2 == 0) pskal.insert({roznice[i], pskal.size()}); else nskal.insert({roznice[i], nskal.size()}); } } int mparz = 1; // rozmiar drzewa dla parzystych while (mparz < pskal.size()) mparz *= 2; //cout<<"mparz = "<<mparz<<endl; int mniep = 1; // rozmiar drzewa dla nieparzystych while (mniep < nskal.size()) mniep *= 2; //cout<<"mniep = "<<mniep<<endl; for (int i = 0; i < n; i++) { if (tab[i] % 2 == 0) { ile[i] = 1; // bierzemy parzyste mniejsze r�wne //cout<<"parzyste <= "<<tab[i]<<endl; map<long long, int>::iterator it = pskal.upper_bound(tab[i]); // pierwszy wi�kszy parzysty (lub end je�li nie ma) int kon = (it == pskal.end()) ? kon = pskal.size() - 1 : it->second - 1; ile[i] += czytaj(parz, 1, mparz, 2 * mparz - 1, mparz, kon + mparz); ile[i] %= M; // bierzemy nieparzyste wi�ksze //cout<<"nieparzyste > "<<tab[i]<<endl; it = nskal.upper_bound(tab[i]); // pierwszy wi�kszy nieparzysty (lub end je�li nie ma) if (it != nskal.end()) { // je�li w og�le jest jaki� nieparzysty int pocz = it->second; ile[i] += czytaj(niep, 1, mniep, 2 * mniep - 1, pocz + mniep, 2 * mniep - 1); ile[i] %= M; } dodaj(parz, pskal[tab[i]] + mparz, ile[i]); } else { // bierzemy nieparzyste mniejsze r�wne //cout<<"nieparzyste <= "<<tab[i]<<endl; map<long long, int>::iterator it = nskal.upper_bound(tab[i]); // pierwszy wi�kszy nieparzysty (lub end je�li nie ma) int kon = (it == nskal.end()) ? nskal.size() - 1 : it->second - 1; ile[i] += czytaj(niep, 1, mniep, 2 * mniep - 1, mniep, kon + mniep); ile[i] %= M; // bierzemy parzyste wi�ksze //cout<<"parzyste > "<<tab[i]<<endl; //cout<<"tab["<<i<<"] = "<<tab[i]<<endl; it = pskal.upper_bound(tab[i]); if (it != pskal.end()) { int pocz = it->second; ile[i] += czytaj(parz, 1, mparz, 2 * mparz - 1, pocz + mparz, 2 * mparz - 1); ile[i] %= M; } dodaj(niep, nskal[tab[i]] + mniep, ile[i]); } //cout<<i<<" "<<tab[i]<<endl; /* if (tab[i] % 2 == 0) ile2[i] = 1; for (int j = 0; j < i; j++) { if (tab[j] <= tab[i] && tab[j] % 2 == tab[i] % 2) { ile2[i] += ile2[j]; ile2[i] %= M; //cout<<"przdluzam mniejsze tej samej parzysto�ci "<<j<<" "<<tab[j]<<" do "<<ile2[i]<<endl; } else if (tab[j] > tab[i] && tab[j] % 2 != tab[i] % 2) { ile2[i] += ile2[j]; ile2[i] %= M; //cout<<"przdluzam wieksze innej parzystosci "<<j<<" "<<tab[j]<<" do "<<ile2[i]<<endl; } } if (ile[i] != ile2[i]) break; */ } cout<<ile[n - 1]<<"\n"; } |
English