#include #include #include using namespace std; using ll = long long; #include #include #include #include using mint = atcoder::modint998244353; using dat1 = pair,pair>; dat1 op1(dat1 a,dat1 b) { dat1 now; now.first.first = a.first.first * b.first.second + b.first.first; now.first.second = a.first.second * b.first.second; return now; } dat1 e1(){ return make_pair(make_pair(0, 1), make_pair(-1, -1)); } using dat2 = int; dat2 op2(dat2 a,dat2 b) { return min(a,b); } dat2 e2() { return 1e9; } using dat3 = int; dat3 op3(dat3 a,dat3 b){ return max(a,b); } dat3 e3(){ return -1; } int fuse = 0; int f1(dat3 a) { return a < fuse; } void solve(){ int n; cin>>n; vector p(n); for(int i = 0;i>p[i]; for(int i = 0;i idx(n); for(int i = 0;i seg1(n); // 数字の index set use; // 場所の index set cutuse; atcoder::segtree pmin(p); atcoder::segtree pmax(p); atcoder::segtree psum(n); atcoder::segtree usemax(n); atcoder::segtree usemin(n); for(int i = 0;i can(n); atcoder::segtree notuse(n); for(int i = 0;i ok(n, 0); atcoder::segtree conmax(n); vector mcan(n); auto judge = [&](int i) { // cout<<"j1"<mx) { // cout<<"j2"< ni); while(r-l>1) { int m = (l+r)/2; int mx = pmax.prod(l, m); if(ni ans(n+1); int last = 0; vector,dat1>> rr; auto cut = [&](int i) { assert(i!=0); auto itr = cutuse.lower_bound(i); int r = n; if(itr!=cutuse.end()) r = *itr; assert(itr!=cutuse.begin()); itr--; int l = *itr; int nl = p[l]; dat1 nnl = seg1.get(nl); rr.push_back(make_pair(make_pair(nl, 0), nnl)); dat1 newl = nnl; newl.second.second = i - 1; newl.first = psum.prod(l, i).first; add(newl, nl); rr.push_back(make_pair(make_pair(nl, 1), newl)); dat1 newi; newi.second.first = i; newi.second.second = r - 1; newi.first = psum.prod(i, r).first; add(newi, p[i]); rr.push_back(make_pair(make_pair(p[i], 1), newi)); }; ans[0] = seg1.all_prod().first.first; for(int t = 1;t < n;) { mint tmp = 0; if(last==n){ ans[t] = seg1.all_prod().first.first; t++; continue; } { int ni = idx[last]; int nj = ni - 1; if(0<=nj && p[nj] == last - 1) { cut(ni); } } // assert(last!=n-1); int ni = last + 1; int need = 0; rr.clear(); int pos = n; if(last-1>=0) pos = idx[last-1] + 1; if(pos!=n && cutuse.find(pos) == cutuse.end()) need++; if(cutuse.find(idx[last])==cutuse.end()) need++; if(need==0){ last++; continue; } if(need==2) { // cout<<"N"< mc); // while(r-l>1){ // int m = (r+l)/2; // assert(0<=l&&l<=m&&m<=m); // if(pmax.prod(l, m) > mc) r = m; // else l = m; // } // assert(r-1!=0); // cut(r-1); }else{ int ni = idx[mn]; cut(ni); } tmp = seg1.all_prod().first.first; reverse(rr.begin(),rr.end()); for(auto e:rr){ if(e.first.second==1) erase(e.first.first); else add(e.second, e.first.first); } fn = true; } // cout<<"N1"<>t; while(t--){ solve(); } }