Topic Portal (internal title 49)
Input Format
The first n-row four integers $, Q, A, B $.
Then $ n $ lines each integer $ p_i $.
Output Format
A row of integer answer.
Sample
Sample input:
10 3 3 7
4
2
8
Sample output:
4
Data range and tips
For $ 30 \% $ data: $ n, q \ leqslant 2,000 $
For all data:
$. 1 \ n-leqslant, Q \ ^. 5 leqslant {10} $
$. 1 \ leqslant P_i \ $ leqslant n-
answer
First, we consider the $ 30 \% $ of the algorithm how to do?
$ $ Considering the DP, defined $ dp [i] [j] $ represents the first step $ I $, $ a pointer $ P_i, another pointer minimum number of steps in the $ J $.
Then we can in the state transition equation:
$ \ Alpha.dp [i] [j] = dp [i-1] [j] + | p_i-p_ {i-1} | $ (the last time and this time a pointer is moved)
$ \ Beta.dp [i] [p_ {i-1}] = dp [i-1] [j] + | p_i-j | $ (the last time and this time is not a movement of the pointer)
So we then consider how to optimize.
Metastatic $ \ alpha $ is actually the entire range have added $ | p_i-p_ {i-1} | $, while the transfer of $ \ beta $ we can maintain $ dp [i] [j] + j $ and $ dp [i] [j] -j $ to minimum.
So consider the tree line optimization, you can get a perfect score.
Time complexity: $ \ Theta (n \ log n) $.
Expectations score: $ 100 $ points.
Actual score: $ 100 $ points.
Code time
#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
int n,q,a,b;
int p[100001];
long long tr[4][400001];
void pushup(int x)
{
tr[0][x]=min(tr[0][L(x)],tr[0][R(x)]);
tr[1][x]=min(tr[1][L(x)],tr[1][R(x)]);
tr[2][x]=min(tr[2][L(x)],tr[2][R(x)]);
}
void pushdown(int x)
{
if(!tr[3][x])return;
tr[0][L(x)]+=tr[3][x];
tr[0][R(x)]+=tr[3][x];
tr[1][L(x)]+=tr[3][x];
tr[1][R(x)]+=tr[3][x];
tr[2][L(x)]+=tr[3][x];
tr[2][R(x)]+=tr[3][x];
tr[3][L(x)]+=tr[3][x];
tr[3][R(x)]+=tr[3][x];
tr[3][x]=0;
}
void build(int x,int l,int r)
{
if(l==r)
{
if(l==b)
{
tr[0][x]=0;
tr[1][x]=l;
tr[2][x]=-l;
}
return;
}
int mid=(l+r)>>1;
build(L(x),l,mid);
build(R(x),mid+1,r);
pushup(x);
}
void change(int x,int l,int r,int w,long long k)
{
if(l==r)
{
tr[0][x]=min(tr[0][x],k);
tr[1][x]=tr[0][x]+l;
tr[2][x]=tr[0][x]-l;
return;
}
int mid=(l+r)>>1;
pushdown(x);
if(w<=mid)change(L(x),l,mid,w,k);
else change(R(x),mid+1,r,w,k);
pushup(x);
}
long long ask1(int x,int l,int r,int L,int R)
{
if(R<l||r<L)return 200209230020020923;
if(L<=l&&r<=R)return tr[2][x];
int mid=(l+r)>>1;
pushdown(x);
return min(ask1(L(x),l,mid,L,R),ask1(R(x),mid+1,r,L,R));
}
long long ask2(int x,int l,int r,int L,int R)
{
if(R<l||r<L)return 200209230020020923;
if(L<=l&&r<=R)return tr[1][x];
int mid=(l+r)>>1;
pushdown(x);
return min(ask2(L(x),l,mid,L,R),ask2(R(x),mid+1,r,L,R));
}
int main()
{
scanf("%d%d%d%d",&n,&q,&a,&b);
memset(tr[0],0x3f,sizeof(tr[0]));
memset(tr[1],0x3f,sizeof(tr[1]));
memset(tr[2],0x3f,sizeof(tr[2]));
build(1,1,n);
for(int i=1;i<=q;i++)
{
scanf("%d",&b);
tr[0][0]=min(ask1(1,1,n,1,b)+b,ask2(1,1,n,b,n)-b);
tr[0][1]+=abs(a-b);
tr[1][1]+=abs(a-b);
tr[2][1]+=abs(a-b);
tr[3][1]+=abs(a-b);
change(1,1,n,a,tr[0][0]);
a=b;
}
cout<<tr[0][1]<<endl;
return 0;
}
rp ++