Description
Solution
对于最优的方案,显然每一次染色都要尽可能多地染色.
所以对于询问
(
l
,
r
)
(l,r)
(l,r),我们可以统计有多少对
(
i
,
j
)
(i,j)
(i,j)使得
1.
l
≤
i
<
j
≤
r
2.
m
i
n
k
=
i
j
a
k
=
a
i
=
a
j
1.l\le i < j \leq r\\ 2.min_{k=i}^{j}{a_k}=a_i=a_j
1.l≤i<j≤r2.mink=ijak=ai=aj
这东西可以离线下来,然后单调栈+树状数组维护
结束.
Code
#include <cstdio>
#include <iostream>
#include <vector>
#define lowbit(x) (x & -x)
using namespace std;
inline int read() {
int res = 0; char ch = getchar();
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) res = (res << 3) + (res << 1) + (ch ^ 48), ch = getchar();
return res;
}
struct QUE{
int l, id;
};
vector <QUE> que[200100];
int n, q, a[200100], tr[200100], stk[200100], top, ans[200100];
void modify(int x) {
while(x <= n) {
tr[x] ++;
x += lowbit(x);
}
}
int query(int x) {
int res = 0;
while(x) {
res += tr[x];
x -= lowbit(x);
}
return res;
}
QUE Que(int x, int y) {
QUE res;
res.id = y, res.l = x;
return res;
}
int main() {
n = read(), q = read();
for(int i = 1; i <= n; ++i)
a[i] = read();
for(int i = 1; i <= q; ++i) {
int l = read(), r = read();
que[r].push_back(Que(l, i));
}
for(int r = 1; r <= n; ++r) {
while(a[stk[top]] > a[r] && top) --top;
if(a[stk[top]] == a[r]) modify(stk[top]);
stk[++top] = r;
for(int i = 0; i < que[r].size(); ++i) {
QUE tmp = que[r][i];
ans[tmp.id] = r - tmp.l + 1 - (query(r) - query(tmp.l - 1));
}
}
for(int i = 1; i <= q; ++i)
printf("%d\n",ans[i]);
return 0;
}