Description
Sequence of a given length n: A1,a2,..., An, recorded as A[1:n]. Similarly, A[l:r] (1≤l≤r≤n) refers to a sequence: al,al+1,..., ar-
1,ar. If 1≤l≤s≤t≤r≤n, it is called A[s:t] is a sub-sequence of a[l:r]. There are now Q queries, each asking for a given two numbers L and R,1≤l≤r
≤n, the sum of the minimum values of different sub-sequences of a[l:r]. For example, given a sequence 5,2,4,1,3, asking for a given two numbers of 1 and 3, then A[1:3] has
6 subsequence A[1:1],a[2:2],a[3:3],a[1:2],a[2:3],a[1:3], the sum of the minimum values of these 6 sub-sequences is 5+2+4+2+2+2=17.
Input
The first line of the input file contains two integers n and q, each representing the sequence length and the number of queries. Next line, containing n integers, separated by a space
, the first integer is AI, which is the value of the first element of the sequence. Next Q line, each row contains two integers l and R, representing a single query.
Output
For each query, the output line represents the answer to the query.
Sample Input5 5
5 2 4) 1 3
1 5
1 3
2 4
3 5
2 5Sample Output28
17
11
11
-HINT
1≤n,q≤100000,| ai| ≤10^9
Positive solution: MO Team Algorithm +st table + monotone stack.
Problem Solving Report:
This problem can be done with the MO team algorithm.
The key to the MO team algorithm is how to calculate the contribution: When I add $r$ to the interval $[l,r-1]$, the $ (r-l+1) $ string is generated, and so many new contributions are made, and then we only consider these new contributions.
So that the minimum value of $[l,r]$ is $t$, it is easy to find that T can produce a contribution of $ (t-l+1) *a[t]$;
For the contribution that $r$ can make, it is advisable to set $last[r]$ to the position of the first element that is smaller than $r$ on the left side of $r$ ($last $ array can obviously be calculated with the monotonic stack $o (n) $), then $r$ 's contribution is $ (r-last[r]) *a[r]$, and so on, $last [R]$ 's contribution is $ (last[r]-last[last[r]]) *a[last[r]]$.
Then we can construct a prefix and something similar to the above, so that $suml[r]$ represents the sum of the contribution of R to each point of 0 as described above, then it can be $suml[r]=suml[last[r]]+ (R-last[r]) *a[r]$. In this way I can complete the effect on the contribution of R join in the $o (1) $ time.
The $r$ deletion is equivalent, as long as it becomes minus. As for the l situation, it is quite similar.
There are some places to be aware of: equal time to take the left, remember to open $long long$, the last stack of the monotonous stack of elements need to be dealt with separately!
It is made by Ljh2000#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio > #include <cmath> #include <algorithm> #include <ctime> #include <vector> #include <queue > #include <map> #include <set> #include <string>using namespace std;typedef long long ll;const int MAXN = 100011; int N,m,belong[maxn],st[maxn][18],l,r;int Last[maxn],next[maxn],stack[maxn],top,block; LL suml[maxn],sumr[maxn],a[maxn],ans,a[maxn];struct ask{int l,r,id,lb;} q[maxn];inline BOOL CMP (ask Q,ask QQ) {if (q.lb==qq.lb) return q.r<qq.r; return q.lb<qq.lb;} inline int getint () {int w=0,q=0; char C=getchar (); while ((c< ' 0 ' | | C> ' 9 ') && c!= '-') C=getchar (); if (c== '-') Q=1,c=getchar (); while (c>= ' 0 ' &&c<= ' 9 ') w=w*10+c-' 0 ', C=getchar (); return q?-w:w;} inline int query (int l,int r) {int t=belong[r-l+1],cc=r-(1<<t) +1;if (A[st[l][t]]<=a[st[cc][t]]) return st[l][t ];return st[cc][t];} inline void Updatel (inT l,int r,int type) {int from=query (L,R); LL suan= (r-from+1) *a[from]/*!!! */;suan+=sumr[l]-sumr[from]; Ans+=type*suan;} inline void Updater (int l,int r,int type) {int from=query (L,R); LL suan= (from-l+1) *a[from]/*!!! */;suan+=suml[r]-suml[from]; Ans+=type*suan;} inline void work () {n=getint (); M=getint (); for (int i=1;i<=n;i++) a[i]=getint (), st[i][0]=i; block=sqrt (n); for (int i= 1;i<=m;i++) Q[i].l=getint (), Q[i].r=getint (), q[i].id=i,q[i].lb= (Q[I].L-1)/block+1;sort (Q+1,Q+M+1,CMP); int from;belong[1]=0; for (int i=2;i<=n;i++) belong[i]=belong[i>>1]+1; A[0]= (1<<30); for (int. j=1;j<=17;j++) for (int i=1;i<=n;i++) {from=i+ (1<< (j-1)); if (From<=n & & A[st[i][j-1]]<=a[st[from][j-1]] st[i][j]=st[i][j-1];else st[i][j]=st[from][j-1];} Top=0; stack[0]=0;for (int i=1;i<=n;i++) {while (top>0 && A[i]<a[stack[top]]) next[stack[top]]=i,top--;last [I]=stack[top];stack[++top]=i;} while (top>0) next[stack[top]]=n+1,top--;for (int i=1;i<=n;i++) Suml[i]=suml[last[i]]+ (LL) (I-last[i]) *a[i];for (int i=n;i>=1;i--) sumr[i]=sumr[next[i]]+ (LL) (next[i]-i) *a[i];ans=a[1]; l=r=1;for (int i=1;i<=m;i++) {while (R<Q[I].R) R++,updater (l,r,1), while (L>Q[I].L) L--, Updatel (l,r,1); R>Q[I].R) Updater (l,r,-1), R--;while (L<Q[I].L) Updatel (l,r,-1), l++; A[q[i].id]=ans;} for (int i=1;i<=m;i++) printf ("%lld\n", A[i]);} int main () {work (); return 0;}
BZOJ4540 [Hnoi2016] Sequence