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
| #include <bits/stdc++.h> using namespace std; typedef long long ll; #define endl '\n' #define int long long mt19937 Rand(chrono::steady_clock::now().time_since_epoch().count()); const int maxn = 8e5+10; const int maxm = maxn*2; const int p = 1e9+7; int raw[maxn]; ll Pow(ll x,ll d,ll p){ll ta=1;if(d==0)return 1%p;x %= p;ll a=Pow(x,d/2,p);ta=a*a%p;if(d%2)ta=ta*x%p;return ta%p;} struct Segtree{ int siz = 1; vector<int>prev,sufv,totv; void init(int n){ while(siz < n)siz *= 2; prev.assign(siz*2,0); sufv.assign(siz*2,0); totv.assign(siz*2,0); } inline int ls(int x){return (x<<1)|1;} inline int rs(int x){return (x<<1)+2;} inline int f(int x){return x*(x+1)/2;} void pushup(int x,int lx,int rx){ int m = (lx+rx)/2; int len = (rx - lx)/2; totv[x] = totv[ls(x)] + totv[rs(x)]; totv[x] += (raw[m-1] <= raw[m]?sufv[ls(x)]*prev[rs(x)]:0); prev[x] = max(prev[ls(x)],(prev[ls(x)] == len and raw[m-1] <= raw[m])?prev[ls(x)] + prev[rs(x)]:0); sufv[x] = max(sufv[rs(x)],(sufv[rs(x)] == len and raw[m-1] <= raw[m])?sufv[rs(x)] + sufv[ls(x)]:0); } void Set(int idx,int v,int x,int lx,int rx){ if(rx - lx == 1){ raw[idx] = v; prev[x] = sufv[x] = totv[x] = 1; return; } int m = (lx+rx)/2; if(lx <= idx and idx < m)Set(idx,v,ls(x),lx,m); else Set(idx,v,rs(x),m,rx); pushup(x,lx,rx); } void Set(int idx,int v){ Set(idx,v,0,0,siz); } ll cal(int l,int r,int x,int lx,int rx){ if(l >= rx or lx >= r)return 0; if(l <= lx and rx <= r)return totv[x]; int m = (lx+rx)/2; ll s1 = cal(l,r,ls(x),lx,m); ll s2 = cal(l,r,rs(x),m,rx); ll ans = s1+s2; if(raw[m-1] <= raw[m]){ ans += max(min(m - l,sufv[ls(x)]),0LL)*max(min(r - m,prev[rs(x)]),0LL); } return ans; } ll cal(int l,int r){ r++; return cal(l,r,0,0,siz); } }; signed main(){ ios::sync_with_stdio(0); cin.tie(0); cout.setf(ios::fixed,ios::floatfield); cout.precision(12); int n,q; Segtree seg; cin >> n >> q; for(int i = 1;i <= n;i++)raw[i] = 0; seg.init(n+1); for(int i = 1;i <= n;i++){ int v; cin >> v; seg.Set(i,v); } while(q--){ int opt,l,r; cin >> opt >> l >> r; if(opt == 1)seg.Set(l,r); else cout << seg.cal(l,r) << endl; } return 0; }
|