#include <bits/stdc++.h> using namespace std; const int N = 300'000 + 7; int n, m, a[N], b[N]; long long ans[N + N]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i <= m; i++) cin >> b[i]; // przedzialy o tej samej dlugosc for (int i = 1; i <= min(n, m); i++) { // cerr << "tyle samo o dlg: " << i << " => " << (n - i + 1) * (m - i + 1) << '\n'; ans[2] += (n - i + 1) * (m - i + 1); } for (int rep : {0, 1}) { // cerr << "REP: " << rep << '\n'; // bierzemy z a przedzial dluzszy i dokladamy krotszy od b for (int i = 1; i <= n; i++) { // cerr << "start: " << i << '\n'; int inc = 1; int dec = 1; vector<int> all; vector<int> ile(n + m); // chemy uzyskac wynik x -> ile potrzeba nam do tego elementow z b auto add = [&](int x) { if (x <= 2) return; // cerr << "adding: " << x << '\n'; for (int y = 2; y <= x; y++) { ile[y] += (x - 2) / (y - 1); } }; auto del = [&](int x) { if (x <= 2) return; // cerr << "deleting: " << x << '\n'; for (int y = 2; y <= x; y++) { ile[y] -= (x - 2) / (y - 1); } }; for (int j = i + 1; j <= n; j++) { if (a[j - 1] < a[j]) { add(dec); dec = 1; inc++; } else { add(inc); inc = 1; dec++; } // cerr << "end: " << j << ' ' << inc << ' ' << dec << ' ' << " | " << a[j - 1] << " vs " << a[j] << '\n'; add(inc); add(dec); int big = min(m, j - i); // najwieksza legalna dlugosc przedzialu z b for (int k = 2; k <= n; k++) { while (big >= ile[k] && big >= 1) { // cerr << "(" << i << "," << j << ") " << rep << " => " << k << ' ' << big << '\n'; ans[k] += m - big + 1; big--; } } del(inc); del(dec); } } swap(n, m); for (int i = 1; i <= max(n, m); i++) swap(a[i], b[i]); } for (int i = 1; i <= n + m; i++) cout << ans[i] % int(1e9 + 7) << ' '; cout << '\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 97 98 99 100 101 102 103 104 105 | #include <bits/stdc++.h> using namespace std; const int N = 300'000 + 7; int n, m, a[N], b[N]; long long ans[N + N]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i <= m; i++) cin >> b[i]; // przedzialy o tej samej dlugosc for (int i = 1; i <= min(n, m); i++) { // cerr << "tyle samo o dlg: " << i << " => " << (n - i + 1) * (m - i + 1) << '\n'; ans[2] += (n - i + 1) * (m - i + 1); } for (int rep : {0, 1}) { // cerr << "REP: " << rep << '\n'; // bierzemy z a przedzial dluzszy i dokladamy krotszy od b for (int i = 1; i <= n; i++) { // cerr << "start: " << i << '\n'; int inc = 1; int dec = 1; vector<int> all; vector<int> ile(n + m); // chemy uzyskac wynik x -> ile potrzeba nam do tego elementow z b auto add = [&](int x) { if (x <= 2) return; // cerr << "adding: " << x << '\n'; for (int y = 2; y <= x; y++) { ile[y] += (x - 2) / (y - 1); } }; auto del = [&](int x) { if (x <= 2) return; // cerr << "deleting: " << x << '\n'; for (int y = 2; y <= x; y++) { ile[y] -= (x - 2) / (y - 1); } }; for (int j = i + 1; j <= n; j++) { if (a[j - 1] < a[j]) { add(dec); dec = 1; inc++; } else { add(inc); inc = 1; dec++; } // cerr << "end: " << j << ' ' << inc << ' ' << dec << ' ' << " | " << a[j - 1] << " vs " << a[j] << '\n'; add(inc); add(dec); int big = min(m, j - i); // najwieksza legalna dlugosc przedzialu z b for (int k = 2; k <= n; k++) { while (big >= ile[k] && big >= 1) { // cerr << "(" << i << "," << j << ") " << rep << " => " << k << ' ' << big << '\n'; ans[k] += m - big + 1; big--; } } del(inc); del(dec); } } swap(n, m); for (int i = 1; i <= max(n, m); i++) swap(a[i], b[i]); } for (int i = 1; i <= n + m; i++) cout << ans[i] % int(1e9 + 7) << ' '; cout << '\n'; return 0; } |