然后i从1开始扫描,每次把能加入的点加入,然后处理右端点为i的查询
#include
#include
#include
#include
using namespace std;
const int MAXN = 100000+5;
const int INF = 0x3f3f3f3f;
int T, N, Q, a[MAXN], s[MAXN], t[MAXN];
int idq[MAXN], q[MAXN], cnt[MAXN], p[MAXN];
int x[MAXN], y[MAXN], ida[MAXN];
int Tr[MAXN<<2], mark[MAXN<<2];
void Build(int idx, int L, int R)
{
Tr[idx] = mark[idx] = 0;
if (L == R)
return;
int left = idx<<1, right = idx<<1|1, mid = (L+R)>>1;
Build(left, L, mid);
Build(right, mid+1, R);
}
void PushDown(int idx)
{
int left = idx<<1, right = idx<<1|1, &mk = mark[idx];
Tr[left] += mk;
mark[left] += mk;
Tr[right] += mk;
mark[right] += mk;
mk = 0;
}
void Update(int idx, int L, int R, int l, int r, int c)
{
if (l <= L && R <= r)
{
Tr[idx] += c;
mark[idx] += c;
return;
}
if (mark[idx])
PushDown(idx);
int left = idx<<1, right = idx<<1|1, mid = (L+R)>>1;
if (l <= mid)
Update(left, L, mid, l, r, c);
if (mid < r)
Update(right, mid+1, R, l, r, c);
}
int Query(int idx, int L, int R, int x)
{
if (x == L && R == x)
return Tr[idx];
if (mark[idx])
PushDown(idx);
int left = idx<<1, right = idx<<1|1, mid = (L+R)>>1;
if (x <= mid)
return Query(left, L, mid, x);
else
return Query(right, mid+1, R, x);
}
bool cmpq(const int &a, const int &b)
{
return t[a] < t[b];
}
bool cmpa(const int &a, const int &b)
{
return y[a] < y[b];
}
int main()
{
//freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
scanf("%d", &T);
for (int cas = 1; cas <= T; cas++)
{
printf("Case %d:\n", cas);
scanf("%d", &N);
stack stal, star;
a[0] = 0;
stal.push(0);
for (int i = 1; i <= N; i++)
{
scanf("%d", &a[i]);
while (a[i] <= a[stal.top()])
stal.pop();
x[i] = stal.top();
stal.push(i);
}
a[N+1] = INF;
star.push(N+1);
for (int i = N; i >= 1; i--)
{
while (a[i] >= a[star.top()])
star.pop();
y[i] = star.top();
star.push(i);
ida[i] = i;
}
sort(ida+1, ida+1+N, cmpa);
scanf("%d", &Q);
for (int i = 1; i <= Q; i++)
{
scanf("%d%d", &s[i], &t[i]);
if (s[i] > t[i])
swap(s[i], t[i]);
idq[i] = i;
q[i] = 0;
}
sort(idq+1, idq+1+Q, cmpq);
Build(1, 1, N);
for (int i = 1, j = 1, k = 1; i <= N; i++)
{
for (; y[ida[k]] == i && k <= N; k++) if (x[ida[k]])
Update(1, 1, N, 1, x[ida[k]], 1);
for (; t[idq[j]] == i && j <= Q; j++)
q[idq[j]] = Query(1, 1, N, s[idq[j]]);
}
for (int i = 1; i <= Q; i++)
printf("%d\n", q[i]);
}
return 0;
}