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 <cassert>
using namespace std;
long long tab[300007];
long long dp[300007];
long long sumk[300007];
// zapytanie: <<pocz, kon>, nr>
int ile_pocz = 0;
bool wyst_pocz[300007];
int ile_kon = 0;
bool wyst_kon[300007];
pair<pair<int, int>, int> zap[300007]; // zapytania
long long odp[300007]; // odp na zapytanie o nr i
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int n, k, q;
cin>>n>>k>>q;
for (int i = 0; i < n; i++) {
cin>>tab[i];
}
for (int i = 0; i < q; i++) {
cin>>zap[i].first.first>>zap[i].first.second;
zap[i].second = i;
if (wyst_pocz[zap[i].first.first] == false) {
wyst_pocz[zap[i].first.first] = true;
ile_pocz++;
}
if (wyst_kon[zap[i].first.second] == false) {
wyst_kon[zap[i].first.second] = true;
ile_kon++;
}
}
//cerr<<"ile_pocz = "<<ile_pocz<<" ile_kon = "<<ile_kon<<endl;
if (ile_kon < ile_pocz) { // op�aca nam si� liczy� dp w drug� stron�
//cerr<<"odwracamy\n";
for (int i = 0; i < n / 2; i++) {
swap(tab[i], tab[n - 1 - i]);
}
for (int i = 0; i < q; i++) {
swap(zap[i].first.first, zap[i].first.second);
zap[i].first.first = n - zap[i].first.first; // 1 -> n - 1; n -> 0 robi si� indeksowanie od 0
zap[i].first.second = n - zap[i].first.second;
}
}
else {
for (int i = 0; i < q; i++) { // zmnieniamy na indeksowanie od 0
zap[i].first.first--;
zap[i].first.second--;
}
}
/*
for (int i = 0; i < n; i++) {
cout<<tab[i]<<" ";
}
cout<<endl;
*/
long long suma = 0;
for (int i = 0; i < n; i++) {
suma += tab[i];
if (i - k >= 0) suma -= tab[i - k];
if (i >= k - 1) sumk[i] = suma;
//cout<<sumk[i]<<" ";
}
/*
cout<<"\n";
for (int i = 0; i < q; i++) {
cout<<zap[i].first.first<<" "<<zap[i].first.second<<endl;
}
*/
sort(zap, zap + q); //rosn�co po pocz�tkach, a je�li r�wne, to rosn�co po ko�cach
int l = 0; // to zapytanie aktualnie liczymy
while (l < q) {
//cerr<<"startuje z "<<zap[l].first.first<<" "<<zap[l].first.second<<endl;
for (int i = zap[l].first.first + k - 1; i <= zap[l].first.second; i++) {
//cerr<<"i = "<<i<<endl;
//assert(dp[i] == 0);
dp[i] = (i - 1 >= zap[l].first.first + k - 1) ? dp[i - 1] : 0;
dp[i] = (i - k >= zap[l].first.first + k - 1) ? max(dp[i], dp[i - k] + sumk[i]) : max(dp[i], sumk[i]);
//dp[i] = max(dp[i - 1], dp[i - k] + sumk[i]);
if (i == zap[l].first.second) {
odp[zap[l].second] = dp[i];
//cerr<<"policzone dla "<<zap[l].first.first<<" "<<zap[l].first.second<<endl;
while (l + 1 < q && zap[l + 1].first == zap[l].first) {
l++;
odp[zap[l].second] = dp[i];
//cerr<<"przy okazji dla "<<zap[l].first.first<<" "<<zap[l].first.second<<endl;
}
if (l + 1 < q && zap[l + 1].first.first == zap[l].first.first) { // je�li nast�pne zapytanie ma ten sam pocz�tek, to przed�u�amy
l++;
//cerr<<"przedluzam do "<<zap[l].first.first<<" "<<zap[l].first.second<<endl;
}
}
}
/*
for (int i = zap[l].first.first + k - 1; i <= zap[l].first.second; i++) {
dp[i] = 0;
}*/
l++; // przesuwamy sie do nowego pocz�tku
}
for (int i = 0; i < q; i++) {
cout<<odp[i]<<"\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 | #include <iostream> #include <algorithm> #include <cassert> using namespace std; long long tab[300007]; long long dp[300007]; long long sumk[300007]; // zapytanie: <<pocz, kon>, nr> int ile_pocz = 0; bool wyst_pocz[300007]; int ile_kon = 0; bool wyst_kon[300007]; pair<pair<int, int>, int> zap[300007]; // zapytania long long odp[300007]; // odp na zapytanie o nr i int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n, k, q; cin>>n>>k>>q; for (int i = 0; i < n; i++) { cin>>tab[i]; } for (int i = 0; i < q; i++) { cin>>zap[i].first.first>>zap[i].first.second; zap[i].second = i; if (wyst_pocz[zap[i].first.first] == false) { wyst_pocz[zap[i].first.first] = true; ile_pocz++; } if (wyst_kon[zap[i].first.second] == false) { wyst_kon[zap[i].first.second] = true; ile_kon++; } } //cerr<<"ile_pocz = "<<ile_pocz<<" ile_kon = "<<ile_kon<<endl; if (ile_kon < ile_pocz) { // op�aca nam si� liczy� dp w drug� stron� //cerr<<"odwracamy\n"; for (int i = 0; i < n / 2; i++) { swap(tab[i], tab[n - 1 - i]); } for (int i = 0; i < q; i++) { swap(zap[i].first.first, zap[i].first.second); zap[i].first.first = n - zap[i].first.first; // 1 -> n - 1; n -> 0 robi si� indeksowanie od 0 zap[i].first.second = n - zap[i].first.second; } } else { for (int i = 0; i < q; i++) { // zmnieniamy na indeksowanie od 0 zap[i].first.first--; zap[i].first.second--; } } /* for (int i = 0; i < n; i++) { cout<<tab[i]<<" "; } cout<<endl; */ long long suma = 0; for (int i = 0; i < n; i++) { suma += tab[i]; if (i - k >= 0) suma -= tab[i - k]; if (i >= k - 1) sumk[i] = suma; //cout<<sumk[i]<<" "; } /* cout<<"\n"; for (int i = 0; i < q; i++) { cout<<zap[i].first.first<<" "<<zap[i].first.second<<endl; } */ sort(zap, zap + q); //rosn�co po pocz�tkach, a je�li r�wne, to rosn�co po ko�cach int l = 0; // to zapytanie aktualnie liczymy while (l < q) { //cerr<<"startuje z "<<zap[l].first.first<<" "<<zap[l].first.second<<endl; for (int i = zap[l].first.first + k - 1; i <= zap[l].first.second; i++) { //cerr<<"i = "<<i<<endl; //assert(dp[i] == 0); dp[i] = (i - 1 >= zap[l].first.first + k - 1) ? dp[i - 1] : 0; dp[i] = (i - k >= zap[l].first.first + k - 1) ? max(dp[i], dp[i - k] + sumk[i]) : max(dp[i], sumk[i]); //dp[i] = max(dp[i - 1], dp[i - k] + sumk[i]); if (i == zap[l].first.second) { odp[zap[l].second] = dp[i]; //cerr<<"policzone dla "<<zap[l].first.first<<" "<<zap[l].first.second<<endl; while (l + 1 < q && zap[l + 1].first == zap[l].first) { l++; odp[zap[l].second] = dp[i]; //cerr<<"przy okazji dla "<<zap[l].first.first<<" "<<zap[l].first.second<<endl; } if (l + 1 < q && zap[l + 1].first.first == zap[l].first.first) { // je�li nast�pne zapytanie ma ten sam pocz�tek, to przed�u�amy l++; //cerr<<"przedluzam do "<<zap[l].first.first<<" "<<zap[l].first.second<<endl; } } } /* for (int i = zap[l].first.first + k - 1; i <= zap[l].first.second; i++) { dp[i] = 0; }*/ l++; // przesuwamy sie do nowego pocz�tku } for (int i = 0; i < q; i++) { cout<<odp[i]<<"\n"; } } |
English