https://lydsy.com/JudgeOnline/problem.php?id=4826

分析:

  莫队+单调栈+st表。

  考虑如何O(1)加入一个点,删除一个点,类似bzoj4540。然后就可以莫队了。复杂度$O(n\sqrt n)$

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<cctype>
 7 #include<set>
 8 #include<queue>
 9 #include<vector>
10 #include<map>
11 using namespace std;
12 typedef long long LL;
13 
14 char buf[100000], *p1 = buf, *p2 = buf;
15 #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
16 inline int read() {
17     int x=0,f=1;char ch=nc();for(;!isdigit(ch);ch=nc())if(ch=='-')f=-1;
18     for(;isdigit(ch);ch=nc())x=x*10+ch-'0';return x*f;
19 }
20 
21 const int N = 200005;
22 struct Edge{
23     int l, r, bel, id;
24     bool operator < (const Edge &A) const {
25         return bel == A.bel ? r < A.r : bel < A.bel;
26     }
27 }Q[N];
28 int cnt[N], a[N], f[N][22], Log[N];
29 int sum1R[N], sum1L[N], sum2R[N], sum2L[N], q[N], mxL[N], mxR[N];
30 int P1, P2, L, R, n, m;
31 LL ans[N], Ans = 0;
32 
33 int getmax(int l,int r) {
34     int k = Log[r - l + 1];
35     int p1 = f[l][k], p2 = f[r - (1 << k) + 1][k];
36     return a[p1] > a[p2] ? p1 : p2;
37 }
38 
39 void updR(int x,int f) {
40     if (L >= R) { Ans = 0; return ; }
41     int p = getmax(L, R - 1), p2 = max(mxL[x], p);
42     Ans += (sum1L[R - 1] - sum1L[p2] + 1) * P1 * f;
43     Ans += (sum1L[p2] - sum1L[p]) * P2 * f;
44     Ans += (sum2L[R - 1] - sum2L[p2]) * P2 * f;
45     if (L > mxL[x]) Ans += (p2 - L) * P2 * f;
46 }
47 
48 void updL(int x,int f) {
49     if (L >= R) { Ans = 0; return ; }
50     int p = getmax(L + 1, R), p2 = min(mxR[x], p);
51     Ans += (sum1R[L + 1] - sum1R[p2] + 1) * P1 * f;
52     Ans += (sum1R[p2] - sum1R[p]) * P2 * f;
53     Ans += (sum2R[L + 1] - sum2R[p2]) * P2 * f;
54     if (R < mxR[x]) Ans += (R - p2) * P2 * f;
55 }
56 
57 int main() {
58     n = read(), m = read();P1 = read(), P2 = read(); 
59     int B = sqrt(n);
60     for (int i = 1; i <= n; ++i) a[i] = read(), f[i][0] = i;
61     for (int j = 1; (1 << j) <= n; ++j) {
62         for (int i = 1; i + (1 << j) - 1 <= n; ++i) {
63             int p1 = f[i][j - 1], p2 = f[i + (1 << (j - 1))][j - 1];
64             f[i][j] = a[p1] > a[p2] ? p1 : p2;
65         }
66     }
67     Log[0] = -1;
68     for (int i = 1; i <= n; ++i) Log[i] = Log[i >> 1] + 1;
69     a[0] = a[n + 1] = 1e9;
70     int l = 1, r = 1; q[1] = 0;
71     for (int i = 1; i <= n; ++i) {
72         while (l <= r && a[i] > a[q[r]]) r --;
73         q[++r] = i;
74         int j = q[r - 1]; mxL[i] = j;        
75         sum2L[i] = sum2L[j] + (i - j - 1); sum1L[i] = sum1L[j] + 1;
76     }
77     l = 1, r = 1; q[1] = n + 1;
78     for (int i = n; i >= 1; --i) {
79         while (l <= r && a[i] > a[q[r]]) r --;
80         q[++r] = i;
81         int j = q[r - 1]; mxR[i] = j;
82         sum2R[i] = sum2R[j] + (j - i - 1); sum1R[i] = sum1R[j] + 1;
83     }
84     for (int i = 1; i <= m; ++i) {
85         Q[i].l = read(), Q[i].r = read(), Q[i].bel = (Q[i].l - 1) / B + 1, Q[i].id = i;
86     }
87     sort(Q + 1, Q + m + 1);
88     L = 1, R = 0;
89     for (int i = 1; i <= m; ++i) {
90         while (L > Q[i].l) L --, updL(L, 1);
91         while (R < Q[i].r) R ++, updR(R, 1);
92         while (L < Q[i].l) updL(L, -1), L ++;
93         while (R > Q[i].r) updR(R, -1), R --;
94         ans[Q[i].id] = Ans;
95     }
96     for (int i = 1; i <= m; ++i) printf("%lld\n", ans[i]);
97     return 0;
98 }
View Code

相关文章:

  • 2021-11-17
  • 2021-08-29
  • 2021-07-23
  • 2021-08-17
  • 2021-05-15
  • 2021-06-01
  • 2021-11-01
  • 2021-08-25
猜你喜欢
  • 2022-02-24
  • 2021-11-01
  • 2021-09-23
  • 2021-11-24
  • 2022-12-23
  • 2022-02-03
  • 2021-10-02
相关资源
相似解决方案