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
| #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 5,P = 998244353,Lg = 18; typedef long long ll; typedef double db; int n,m,inv[N]; int a[N]; ll sum[N]; int s2[N]; struct Node { ll s;int c,l,r; Node(){} Node(const ll _s,const int _c,const int _l,const int _r):s(_s),c(_c),l(_l),r(_r){} Node operator + (const Node &rhs) const { return Node(s + rhs.s,c + rhs.c,min(l,rhs.l),max(r,rhs.r));} bool operator < (const Node &rhs) const { return (__int128) s * rhs.c < (__int128) rhs.s * c;} }; inline int Getval(int l,int r) { int res = (s2[r] - s2[l - 1] + P) % P,sm = (sum[r] - sum[l - 1]) % P; res = (res + P - 1ll * sm * sm % P * inv[r - l + 1] % P) % P; return res; } inline int Getvc(int l,int r,int x,int y) { int res = (s2[r] - s2[l - 1] + P) % P,sm = (sum[r] - sum[l - 1]) % P; res = (res - 1ll * x * x % P + 1ll * y * y % P) % P; sm = (sm - x + y) % P; if(res < 0) res += P;if(sm < 0) sm += P; res = (res + P - 1ll * sm * sm % P * inv[r - l + 1] % P) % P; return res; } inline Node Getave(int l,int r) { if(l > r) return Node(0,0,0,0);return Node(sum[r] - sum[l - 1],r - l + 1,l,r);} int pre[N],suf[N]; int ac1[Lg][N],ac2[Lg][N]; Node t1[N],t2[N]; Node sum1[Lg][N]; int dep1[N],dep2[N]; int fv[N],gv[N]; inline void Build() { t1[0] = Node(0,1,0,0);t2[n + 1] = Node(1e9,1,n+1,0); for(int i = 1;i <= n;i++) { Node now(a[i],1,i,i); int p = i - 1; while(p && now < t1[p]) now = now + t1[p],p = pre[p]; pre[i] = p;t1[i] = now; dep1[i] = dep1[pre[i]] + 1; fv[i] = (fv[pre[i]] + Getval(now.l,now.r)) % P; } for(int i = n;i >= 1;i--) { Node now(a[i],1,i,i); int p = i + 1; while(p != n + 1 && t2[p] < now) now = now + t2[p],p = suf[p]; suf[i] = p;t2[i] = now; dep2[i] = dep2[suf[i]] + 1; gv[i] = (gv[suf[i]] + Getval(now.l,now.r)) % P; } for(int i = 1;i <= n;i++) { ac1[0][i] = pre[i],ac2[0][i] = suf[i]; sum1[0][i] = t1[i]; } for(int j = 1;j < Lg;j++) for(int i = 1;i <= n;i++) { ac1[j][i] = ac1[j - 1][ac1[j - 1][i]]; ac2[j][i] = ac2[j - 1][ac2[j - 1][i]]; sum1[j][i] = sum1[j - 1][i] + sum1[j - 1][ac1[j - 1][i]]; } } inline int jump(int op,int x,int k) { for(int i = Lg - 1;i >= 0;i--) if((k >> i) & 1) x = (op == 1) ? ac1[i][x] : ac2[i][x]; return x; } inline int GetL(int x,int y,int R) { if(x == 1) return 1; Node rig = (R ? Getave(x + 1,t2[R].r) : Node(0,0,1e9,0)); if(t1[x - 1] < Node(y,1,x,x) + rig) return x; if(t1[pre[x - 1]] < t1[x - 1] + Node(y,1,x,x) + rig) return x - 1; int now = x - 1; Node sm(0,0,0,0); for(int i = Lg - 1;i >= 0;i--) { Node val = sm + sum1[i][now]; int nx = ac1[i][now]; val = val + Node(y,1,x,x) + rig; if(!(t1[nx] < val)) sm = sm + sum1[i][now],now = nx; } return now; } inline int Solve(int x,int y) { int kl = 0,kr = 0; int lef = 0,rig = dep2[x + 1] - 1; while(lef < rig) { int mid = lef + rig >> 1; int now = jump(2,x + 1,mid); int l0 = GetL(x,y,now),ll = l0 < x ? t1[l0].l : l0; Node val = Getave(ll,x - 1) + Node(y,1,x,x) + Getave(x + 1,t2[now].r); if(val < t2[suf[now]]) rig = mid; else lef = mid + 1; } int tt = GetL(x,y,0),ttl = tt < x ? t1[tt].l : tt; if(Getave(ttl,x - 1) + Node(y,1,x,x) < t2[x + 1]) kr = x; else kr = t2[jump(2,x + 1,lef)].r; kl = (kr == x) ? tt : GetL(x,y,jump(2,x + 1,lef)); if(kl < x) kl = t1[kl].l; return (1ll * fv[kl - 1] + gv[kr + 1] + Getvc(kl,kr,a[x],y)) % P; } int main() { cin >> n >> m; for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 1;i <= n;i++) sum[i] = sum[i - 1] + a[i],s2[i] = (s2[i - 1] + 1ll * a[i] * a[i] % P) % P; inv[1] = 1; for(int i = 2;i <= n;i++) inv[i] = 1ll * inv[P % i] * (P - P / i) % P; Build(); cout << fv[n] << endl; for(int i = 1;i <= m;i++) { int x,y; cin >> x >> y; cout << Solve(x,y) << endl; } return 0; }
|