Reference: https://www.cnblogs.com/lcf-2000/p/6789680.html
This is a relatively small amount of practice, using the interval to modify the interval query tree array, see: www.cnblogs.com/lcf-2000/p/5866170.html#3830447
Enumeration Max A[i], find L[i],r[i] is the last one on the left than it is larger and the right one is larger than it, consider contributing:
P1: Each query to be added first (r-l) *P1 is point to adjacent, and then to R[i] has P1 contribution to the left end is l[i]
P2: Contribution to L[i] (i+1,r[i]-1), Contribution to R[i] (l[i]+1,i-1)
Offline sorting + scan line to do the line, the situation should be taken into account.
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespaceStdConst intn=400005;intN,m,p1,p2,a[n],s[n],top,r[n],l[n],tot;Long LongAns[n],c1[n],c2[n];structqwe{intL,r,x,b,z; Qwe (intL=0,intR=0,intx=0,intb=0,intz=0) {l=l,r=r,x=x,b=b,z=z; }}b[n],c[n];BOOLcmpConstQwe &a,ConstQwe &b) {returna.x<b.x;}intRead () {intR=0, f=1;CharP=getchar (); while(p>' 9 '|| p<' 0 ') {if(p=='-') f=-1; P=getchar (); } while(p>=' 0 '&&p<=' 9 ') {r=r*Ten+p-48; P=getchar (); }returnR*f;}intlbintx) {returnx& (-X);}voidAddintXintV) {if(!x)return; for(intI=X;I<=N;I+=LB (i)) c1[i]+=v,c2[i]+=1ll*x*v;}Long LongQues (intx) {Long LongRe=0; for(intI=x;i>0; i-=lb (i)) re+= (x+1) *c1[i]-c2[i];returnRe;}intMain () {N=read (), M=read (), P1=read (), P2=read (); a[0]=a[n+1]=n+1; s[top=1]=0; for(intI=1; i<=n+1; i++) {if(i<=n) A[i]=read (); while(A[s[top]]<a[i]) r[s[top--]]=i; L[i]=s[top]; S[++top]=i; } for(intI=1; i<=m;i++) {intL=read (), R=read (); ans[i]+= (r-l) *p1;contribution generated by//adjacent two pointsB[i]=qwe (l,r,l-1I-1); B[i+m]=qwe (L,r,r,i,1); } sort (b+1B+1+2*M,CMP); for(intI=1; i<=n;i++) {if(l[i]&&r[i]<=n) c[++tot]=qwe (L[i],l[i],r[i],0, p1);if(L[i]&&r[i]>i+1) C[++tot]=qwe (i+1, R[i]-1, L[i],0, p2);if(R[i]<=n&&i>l[i]+1) C[++tot]=qwe (L[i]+1, I-1, R[i],0, p2); } sort (c+1C+1+TOT,CMP);intw1=1, w2=1; while(!b[w1].x) w1++; for(intI=1; w1<=m*2&&i<=n;i++)//Scan line{ while(w2<=tot&&c[w2].x==i) {Add (C[W2].R+1,-c[w2].z); Add (C[W2].L,C[W2].Z); w2++; } while(w1<=2*m&&b[w1].x==i) {ans[b[w1].b]+=b[w1].z* (ques (B[W1].R)-ques (B[W1].L-1)); w1++; } } for(intI=1; i<=m;i++) printf ("%lld\n", Ans[i]);return 0;}
Bzoj 4826: [Hnoi2017] Shadow Demon "monotone stack + Tree array + scan line"