题意:
思路:From http://blog.csdn.net/neither_nor/article/details/70211150
对每个点i,单调栈求出左边和右边第一个大于i的位置,记为l[i]和r[i]
那么(l[i],r[i])会产生p1的贡献
左端点为l[i],右端点在[i+1,r-1]的点对都会产生p1的贡献
右端点为r[i],左端点在[l+1,i-1]的点对都会产生p2的贡献
将点对看成平面上的点,横坐标左端点纵坐标右端点,上述贡献分别对应单点加和线段加
查询就是矩形求和
From MG:
考虑修改均为如(x,y1..y2)与(x1..x2,y)形式
因为询问均为矩形,则修改(y1..y2,x)与(x,y1..y2)等价
若统一转化为(x,y1..y2)形式,可用主席树维护
若统一转化为(y1..y2,x)形式,可用树状数组套主席树维护
注意点对(i,i)都有p1的贡献
1 var t:array[0..10000000]of record 2 a,s:int64; 3 l,r:longint; 4 end; 5 d:array[1..1000000,1..4]of longint; 6 l,r:array[1..300000]of longint; 7 root,stk,a:array[0..300000]of longint; 8 n,m,i,cnt,j,top,que,x,y,p1,p2:longint; 9 ans:int64; 10 11 procedure update(l,r,x,y,v:longint;var p:longint); 12 var mid:longint; 13 begin 14 if (l>x)or(x>y) then exit; 15 inc(cnt); t[cnt]:=t[p]; p:=cnt; 16 t[p].s:=t[p].s+int64(v)*(y-x+1); 17 if (l=x)and(r=y) then 18 begin 19 t[p].a:=t[p].a+v; 20 exit; 21 end; 22 mid:=(l+r)>>1; 23 if y<=mid then update(l,mid,x,y,v,t[p].l) 24 else if x>mid then update(mid+1,r,x,y,v,t[p].r) 25 else 26 begin 27 update(l,mid,x,mid,v,t[p].l); 28 update(mid+1,r,mid+1,y,v,t[p].r); 29 end; 30 end; 31 32 procedure query(l,r,x,y,p1,p2:longint); 33 var mid:longint; 34 begin 35 if (l=x)and(r=y) then 36 begin 37 ans:=ans+t[p1].s-t[p2].s; 38 exit; 39 end; 40 ans:=ans+(t[p1].a-t[p2].a)*(y-x+1); 41 mid:=(l+r)>>1; 42 if y<=mid then query(l,mid,x,y,t[p1].l,t[p2].l) 43 else if x>mid then query(mid+1,r,x,y,t[p1].r,t[p2].r) 44 else 45 begin 46 query(l,mid,x,mid,t[p1].l,t[p2].l); 47 query(mid+1,r,mid+1,y,t[p1].r,t[p2].r); 48 end; 49 end; 50 51 procedure swap(var x,y:longint); 52 var t:longint; 53 begin 54 t:=x; x:=y; y:=t; 55 end; 56 57 procedure qsort(l,r:longint); 58 var i,j,mid:longint; 59 begin 60 i:=l; j:=r; mid:=d[(l+r)>>1,1]; 61 repeat 62 while mid>d[i,1] do inc(i); 63 while mid<d[j,1] do dec(j); 64 if i<=j then 65 begin 66 swap(d[i,1],d[j,1]); 67 swap(d[i,2],d[j,2]); 68 swap(d[i,3],d[j,3]); 69 swap(d[i,4],d[j,4]); 70 inc(i); dec(j); 71 end; 72 until i>j; 73 if l<j then qsort(l,j); 74 if i<r then qsort(i,r); 75 end; 76 77 begin 78 assign(input,'bzoj4826.in'); reset(input); 79 assign(output,'bzoj4826.out'); rewrite(output); 80 readln(n,que,p1,p2); 81 for i:=1 to n do read(a[i]); 82 top:=1; stk[top]:=0; a[0]:=maxlongint; 83 for i:=1 to n do 84 begin 85 while (top>0)and(a[i]>a[stk[top]]) do dec(top); 86 if top=1 then l[i]:=0 87 else l[i]:=stk[top]; 88 inc(top); stk[top]:=i; 89 end; 90 top:=1; stk[top]:=n+1; a[n+1]:=maxlongint; 91 for i:=n downto 1 do 92 begin 93 while (top>0)and(a[i]>a[stk[top]]) do dec(top); 94 if top=1 then r[i]:=n+1 95 else r[i]:=stk[top]; 96 inc(top); stk[top]:=i; 97 end; 98 for i:=1 to n do 99 begin 100 if (l[i]>0)and(r[i]<=n) then 101 begin 102 inc(m); d[m,1]:=l[i]; d[m,2]:=r[i]; d[m,3]:=r[i]; d[m,4]:=p1; 103 end; 104 if l[i]>0 then 105 begin 106 inc(m); d[m,1]:=l[i]; d[m,2]:=i+1; d[m,3]:=r[i]-1; d[m,4]:=p2; 107 end; 108 if r[i]<=n then 109 begin 110 inc(m); d[m,1]:=r[i]; d[m,2]:=l[i]+1; d[m,3]:=i-1; d[m,4]:=p2; 111 end; 112 end; 113 qsort(1,m); 114 j:=1; 115 for i:=1 to n do 116 begin 117 root[i]:=root[i-1]; 118 while (j<=m)and(d[j,1]=i) do 119 begin 120 update(1,n,d[j,2],d[j,3],d[j,4],root[i]); 121 inc(j); 122 end; 123 end; 124 for i:=1 to que do 125 begin 126 readln(x,y); 127 ans:=(y-x)*p1; 128 query(1,n,x,y,root[y],root[x-1]); 129 writeln(ans); 130 end; 131 close(input); 132 close(output); 133 end.