#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 6e5 + 5, Mod = 1e9 + 7;
inline ll sqr(ll x){
return x * x % Mod;
}
inline void upd(ll &x, ll dx){
x = (x + dx) % Mod;
}
class bit{
private:
ll n, t[N];
public:
inline void init(ll n0){
n = n0;
for(ll i = 1 ; i <= n ; i ++) t[i] = 0;
}
inline ll lowbit(ll x){
return x & -x;
}
inline void modify(ll p, ll x){
x = (x * (Mod + 1) / 2) % Mod;
while(p <= n){
upd(t[p], x);
p = p + lowbit(p);
}
}
inline ll qry(ll p){
ll ret = 0;
while(p > 0){
upd(ret, t[p]);
p = p - lowbit(p);
}
return ret;
}
inline ll query(ll l, ll r){
return (qry(r) - qry(l - 1) + Mod) % Mod;
}
} f, g, h;
ll n = 0, m = 0, k = 0, a[N] = {}, b[N] = {}, pre[N] = {}, suf[N] = {}, ans[N] = {};
vector<ll> pos[N] = {};
inline void init(){
memset(pre, 0, sizeof(pre)), memset(suf, 0, sizeof(suf));
k = 0, memset(b, 0, sizeof(b));
for(ll i = 0 ; i < N ; i ++) pos[i].clear();
}
inline void solve(){
for(ll i = 2, p = 0, x = 1 ; i <= n ; i ++){
if(a[i] < a[i - 1]){
if(p == 1){
b[++ k] = x;
p = -1, x = 1;
}
else p = -1, x ++;
}
else{
if(p == -1){
b[++ k] = x;
p = 1, x = 1;
}
else p = 1, x ++;
}
if(i == n) b[++ k] = x;
}
for(ll i = 1 ; i <= k ; i ++){
for(ll x = 3 ; x <= b[i] ; x ++) upd(suf[x], (b[i] - x + 1));
for(ll x = 1 ; x <= b[i] ; x ++) pos[x].push_back(i);
pre[i] = pre[i - 1] + b[i];
}
for(ll x = n ; x >= 1 ; x --) upd(suf[x], suf[x + 1]);
for(ll x = 1 ; x <= n ; x ++) for(ll d = 1 ; (d + 1) * x <= n && d <= m ; d ++) upd(ans[x], suf[(d + 1) * x + 2] * (m - d + 1));
for(ll x = 1 ; x <= n ; x ++){
f.init(n / x + 5), g.init(n / x + 5), h.init(n / x + 5);
ll cur = 1, j = 0;
for(ll i : pos[x]){
if(j != i - 1){
ll val = pre[i - 1] - pre[j], l = max(cur - m, 1ll), r = cur - 1, z = cur - 1;
upd(ans[x], (((2 * m + 1) * z + Mod - sqr(z)) % Mod * f.query(l, r) + (2 * z + Mod - 2 * m - 1) % Mod * g.query(l, r) + (Mod - 1) * h.query(l, r)) % Mod * val);
if(l > 1) upd(ans[x], ((m + 1) * m) % Mod * f.query(1, l - 1) % Mod * val);
f.modify(cur, val), g.modify(cur, val * cur % Mod), h.modify(cur, val * sqr(cur) % Mod);
}
if(i > 1) for(ll s = 1 ; s <= b[i] ; ){
ll t = min(s + x - 1, b[i]), val = t - s + 1; if(s > 1) cur ++;
ll l = max(cur - m, 1ll), r = cur - 1, z = cur - 1;
upd(ans[x], (((2 * m + 1) * z + Mod - sqr(z)) % Mod * f.query(l, r) + (2 * z + Mod - 2 * m - 1) % Mod * g.query(l, r) + (Mod - 1) * h.query(l, r)) % Mod * val);
if(l > 1) upd(ans[x], ((m + 1) * m) % Mod * f.query(1, l - 1) % Mod * val);
s = t + 1;
}
else cur += (b[i] - 1) / x;
ll las = cur;
for(ll s = 1 ; s <= b[i] ;){
ll t = min((s == 1) ? (x + 1) : (s + x - 1), b[i]), val = t - s + 1; if(s > 1) cur --;
f.modify(cur, val), g.modify(cur, val * cur % Mod), h.modify(cur, val * sqr(cur) % Mod);
s = t + 1;
}
cur = las, j = i;
}
if(j != k){
ll val = pre[k] - pre[j], l = max(cur - m, 1ll), r = cur - 1, z = cur - 1;
upd(ans[x], (((2 * m + 1) * z + Mod - sqr(z)) % Mod * f.query(l, r) + (2 * z + Mod - 2 * m - 1) % Mod * g.query(l, r) + (Mod - 1) * h.query(l, r)) % Mod * val);
if(l > 1) upd(ans[x], ((m + 1) * m) % Mod * f.query(1, l - 1) % Mod * val);
}
}
}
int main(){
scanf("%lld %lld", &n, &m);
for(ll i = 1 ; i <= n ; i ++) scanf("%lld", &a[i]);
init(), solve();
swap(n, m);
for(ll i = 1 ; i <= n ; i ++) scanf("%lld", &a[i]);
init(), solve();
ans[0] = ((n * (n + 1) / 2) % Mod) * ((m * (m + 1) / 2) % Mod) % Mod;
for(ll i = 0 ; i < n + m - 1 ; i ++) ans[i] = (ans[i] + Mod - ans[i + 1]) % Mod;
printf("0 ");
for(ll i = 0 ; i < n + m - 1 ; i ++) printf("%lld ", ans[i]);
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 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 | #include<bits/stdc++.h> using namespace std; typedef long long ll; const ll N = 6e5 + 5, Mod = 1e9 + 7; inline ll sqr(ll x){ return x * x % Mod; } inline void upd(ll &x, ll dx){ x = (x + dx) % Mod; } class bit{ private: ll n, t[N]; public: inline void init(ll n0){ n = n0; for(ll i = 1 ; i <= n ; i ++) t[i] = 0; } inline ll lowbit(ll x){ return x & -x; } inline void modify(ll p, ll x){ x = (x * (Mod + 1) / 2) % Mod; while(p <= n){ upd(t[p], x); p = p + lowbit(p); } } inline ll qry(ll p){ ll ret = 0; while(p > 0){ upd(ret, t[p]); p = p - lowbit(p); } return ret; } inline ll query(ll l, ll r){ return (qry(r) - qry(l - 1) + Mod) % Mod; } } f, g, h; ll n = 0, m = 0, k = 0, a[N] = {}, b[N] = {}, pre[N] = {}, suf[N] = {}, ans[N] = {}; vector<ll> pos[N] = {}; inline void init(){ memset(pre, 0, sizeof(pre)), memset(suf, 0, sizeof(suf)); k = 0, memset(b, 0, sizeof(b)); for(ll i = 0 ; i < N ; i ++) pos[i].clear(); } inline void solve(){ for(ll i = 2, p = 0, x = 1 ; i <= n ; i ++){ if(a[i] < a[i - 1]){ if(p == 1){ b[++ k] = x; p = -1, x = 1; } else p = -1, x ++; } else{ if(p == -1){ b[++ k] = x; p = 1, x = 1; } else p = 1, x ++; } if(i == n) b[++ k] = x; } for(ll i = 1 ; i <= k ; i ++){ for(ll x = 3 ; x <= b[i] ; x ++) upd(suf[x], (b[i] - x + 1)); for(ll x = 1 ; x <= b[i] ; x ++) pos[x].push_back(i); pre[i] = pre[i - 1] + b[i]; } for(ll x = n ; x >= 1 ; x --) upd(suf[x], suf[x + 1]); for(ll x = 1 ; x <= n ; x ++) for(ll d = 1 ; (d + 1) * x <= n && d <= m ; d ++) upd(ans[x], suf[(d + 1) * x + 2] * (m - d + 1)); for(ll x = 1 ; x <= n ; x ++){ f.init(n / x + 5), g.init(n / x + 5), h.init(n / x + 5); ll cur = 1, j = 0; for(ll i : pos[x]){ if(j != i - 1){ ll val = pre[i - 1] - pre[j], l = max(cur - m, 1ll), r = cur - 1, z = cur - 1; upd(ans[x], (((2 * m + 1) * z + Mod - sqr(z)) % Mod * f.query(l, r) + (2 * z + Mod - 2 * m - 1) % Mod * g.query(l, r) + (Mod - 1) * h.query(l, r)) % Mod * val); if(l > 1) upd(ans[x], ((m + 1) * m) % Mod * f.query(1, l - 1) % Mod * val); f.modify(cur, val), g.modify(cur, val * cur % Mod), h.modify(cur, val * sqr(cur) % Mod); } if(i > 1) for(ll s = 1 ; s <= b[i] ; ){ ll t = min(s + x - 1, b[i]), val = t - s + 1; if(s > 1) cur ++; ll l = max(cur - m, 1ll), r = cur - 1, z = cur - 1; upd(ans[x], (((2 * m + 1) * z + Mod - sqr(z)) % Mod * f.query(l, r) + (2 * z + Mod - 2 * m - 1) % Mod * g.query(l, r) + (Mod - 1) * h.query(l, r)) % Mod * val); if(l > 1) upd(ans[x], ((m + 1) * m) % Mod * f.query(1, l - 1) % Mod * val); s = t + 1; } else cur += (b[i] - 1) / x; ll las = cur; for(ll s = 1 ; s <= b[i] ;){ ll t = min((s == 1) ? (x + 1) : (s + x - 1), b[i]), val = t - s + 1; if(s > 1) cur --; f.modify(cur, val), g.modify(cur, val * cur % Mod), h.modify(cur, val * sqr(cur) % Mod); s = t + 1; } cur = las, j = i; } if(j != k){ ll val = pre[k] - pre[j], l = max(cur - m, 1ll), r = cur - 1, z = cur - 1; upd(ans[x], (((2 * m + 1) * z + Mod - sqr(z)) % Mod * f.query(l, r) + (2 * z + Mod - 2 * m - 1) % Mod * g.query(l, r) + (Mod - 1) * h.query(l, r)) % Mod * val); if(l > 1) upd(ans[x], ((m + 1) * m) % Mod * f.query(1, l - 1) % Mod * val); } } } int main(){ scanf("%lld %lld", &n, &m); for(ll i = 1 ; i <= n ; i ++) scanf("%lld", &a[i]); init(), solve(); swap(n, m); for(ll i = 1 ; i <= n ; i ++) scanf("%lld", &a[i]); init(), solve(); ans[0] = ((n * (n + 1) / 2) % Mod) * ((m * (m + 1) / 2) % Mod) % Mod; for(ll i = 0 ; i < n + m - 1 ; i ++) ans[i] = (ans[i] + Mod - ans[i + 1]) % Mod; printf("0 "); for(ll i = 0 ; i < n + m - 1 ; i ++) printf("%lld ", ans[i]); return 0; } |
English