题目连接:https://vjudge.net/problem/UVA-11374
思路:最短路+记录路径
#include <bits/stdc++.h>
#define MAXN 100005
#define lson num << 1
#define rson num << 1 | 1
using namespace std;
struct node
{
int l,r;
int Max,pos;
}tree[MAXN << 2];
int a[MAXN],d1[MAXN],d2[MAXN];
int cur;
void pushup(int num)
{
tree[num].Max = max(tree[lson].Max,tree[rson].Max);
if(tree[lson].Max >= tree[rson].Max) tree[num].pos = tree[lson].pos;
else tree[num].pos = tree[rson].pos;
}
void build(int num,int l,int r)
{
tree[num].l = l;
tree[num].r = r;
if(l == r) {
tree[num].Max = a[l];
tree[num].pos = l;
return;
}
int mid = (l + r) >> 1;
build(lson,l,mid);
build(rson,mid + 1,r);
pushup(num);
}
void query1(int num,int l,int r,int val)
{
if(tree[num].l == tree[num].r) {
if(tree[num].Max > val) cur = min(cur,tree[num].l);
return;
}
int mid = (tree[num].l + tree[num].r) >> 1;
if(tree[num].l == l && tree[num].r == r) {
if(tree[lson].Max > val) query1(lson,l,mid,val);
else if(tree[rson].Max > val) query1(rson,mid + 1,r,val);
return;
}
if(r <= mid) query1(lson,l,r,val);
else if(l > mid) query1(rson,l,r,val);
else {
query1(lson,l,mid,val);
query1(rson,mid + 1,r,val);
}
}
void query2(int num,int l,int r)
{
if(tree[num].l == l && tree[num].r == r) {
if(tree[num].Max > a[cur]) cur = tree[num].pos;
return;
}
int mid = (tree[num].l + tree[num].r) >> 1;
if(r <= mid) query2(lson,l,r);
else if(l > mid) query2(rson,l,r);
else {
query2(lson,l,mid);
query2(rson,mid + 1,r);
}
}
int main(void)
{
int T,n,m,Max,pos,val,ans;
scanf("%d",&T);
while(T--) {
memset(d1,0,sizeof(d1));
memset(d2,0,sizeof(d2));
scanf("%d %d",&n,&m);
Max = 0;
for(int i = 1; i <= n; i++) {
scanf("%d",&a[i]);
if(a[i] > Max) {
d1[i] = d1[i - 1] + 1;
Max = a[i];
}
else d1[i] = d1[i - 1];
}
build(1,1,n);
d2[n] = 1;
for(int i = n - 1; i >= 1; i--) {
cur = n + 1;
query1(1,i + 1,n,a[i]);
d2[i] = d2[cur] + 1;
}
while(m--) {
ans = cur = 0;
scanf("%d %d",&pos,&val);
if(pos != 1) query2(1,1,pos - 1);
ans += d1[cur];
if(val > a[cur]) ans++;
else val = a[cur];
cur = n + 1;
if(pos != n) query1(1,pos + 1,n,val);
ans += d2[cur];
printf("%d\n",ans);
}
}
return 0;
}
/*
1
5 3
1 2 3 4 4
1 5
5 5
2 3
*/