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 135 136
| #include<bits/stdc++.h> #define inf 0x3f3f3f3f3f3f3f3fll #define debug(x) cerr<<#x<<"="<<x<<endl using namespace std; using ll=long long; using ld=long double; using pli=pair<ll,int>; using pi=pair<int,int>; template<typename A> using vc=vector<A>; using pil=pair<int,ll>; inline int read() { int s=0,w=1;char ch; while((ch=getchar())>'9'||ch<'0') if(ch=='-') w=-1; while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w; } inline ll lread() { ll s=0,w=1;char ch; while((ch=getchar())>'9'||ch<'0') if(ch=='-') w=-1; while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w; } const int mod=998244353; mt19937 _rand(1145141); inline int rand(int l,int r) { return _rand()%(r-l+1)+l; } struct node { int l,r,id; }b[200001]; int sta[200001],top; vc<pil>g[200001]; bool vis[200001]; ll qans[200001]; ll sum1[200001]; ll sum2[501]; int to[200001][2]; int son[200001][2]; ll pre[200001]; int fa[200001]; int wh[200001]; int ra[200001]; int a[200001]; int n,m,sq; inline void Add(ll &a,ll b) { a+=b; if(a>=mod) a-=mod; } inline void add(int x,int y) { Add(sum1[x],y); Add(sum2[wh[x]],y); } inline ll get(int x) { ll ans=0; for(int i=1;i!=wh[x];i++) Add(ans,sum2[i]); for(int i=x;wh[i]==wh[x];i--) Add(ans,sum1[i]); return ans; } inline void push(int w,int v) { int d=-1;ll t=1,sum=1; while(w) { add(a[w],t); if(vis[w]&&d!=-1) { g[to[w][!d]].push_back(pil(v,t)); g[to[w][d]].push_back(pil(v,sum)); break; } int dir=son[fa[w]][1]==w; if(dir==d) Add(sum,t); else swap(sum,t),Add(sum,t); d=dir,w=fa[w]; } } void dfs(int p,int l,int r) { if(son[p][0]) to[son[p][0]][1]=fa[son[p][0]]=p,to[son[p][0]][0]=to[p][0],dfs(son[p][0],l,p-1); if(son[p][1]) to[son[p][1]][0]=fa[son[p][1]]=p,to[son[p][1]][1]=to[p][1],dfs(son[p][1],p+1,r); } inline void run(int s) { memset(pre,0,sizeof(pre));pre[a[s]]=1; for(int i=1;i<=n;i++) { int p=ra[i]; if(to[p][0]) Add(pre[a[to[p][0]]],pre[i]); if(to[p][1]) Add(pre[a[to[p][1]]],pre[i]); } for(int i=1;i<=n;i++) Add(pre[i],pre[i-1]);
ll sum=0;unsigned now=0; for(int i=1;i<=m;i++) { while(now<g[s].size()&&g[s][now].first>=b[i].l) Add(sum,g[s][now++].second); Add(qans[b[i].id],pre[b[i].r]*sum%mod); } } int main() { n=read(),m=read(); for(;(sq+1)*(sq+1)<=n;sq++); int rest=sq; for(int i=n;i;i--) if(rand(1,i)<=rest) rest--,vis[i]=1; for(int i=1;i<=n;i++) { ra[a[i]=read()]=i,wh[i]=(i+sq-1)/sq; while(top&&a[i]>a[sta[top]]) son[i][0]=sta[top--]; son[sta[top]][1]=i,sta[++top]=i; } dfs(son[0][1],1,n); for(int i=1;i<=m;i++) b[i].l=read(),b[i].r=read(),b[i].id=i; sort(b+1,b+m+1,[](node a,node b){ return a.l>b.l;});
int now=n; for(int i=1;i<=m;i++) { while(now>=b[i].l) push(ra[now],now),now--; qans[b[i].id]=get(b[i].r); }
for(int i=1;i<=n;i++) if(g[i].size()) run(i);
for(int i=1;i<=m;i++) printf("%lld\n",qans[i]); return 0; }
|