题目:
Let's define pi(n)pi(n) as the following permutation: [i,1,2,…,i−1,i+1,…,n][i,1,2,…,i−1,i+1,…,n]. This means that the ii-th permutation is almost identity(i.e. which maps every element to itself) permutation but the element ii is on the first position. Examples:
You are given an array x1,x2,…,xmx1,x2,…,xm (1≤xi≤n1≤xi≤n).
Let pos(p,val)pos(p,val) be the position of the element valval in pp. So, pos(p1(4),3)=3,pos(p2(4),2)=1,pos(p4(4),4)=1
Let's define a function f(p)=∑i=1m−1|pos(p,xi)−pos(p,xi+1)|f(p)=∑i=1m−1|pos(p,xi)−pos(p,xi+1)|, where |val||val| is the absolute value of valval. This function means the sum of distances between adjacent elements of xx in pp.
Your task is to calculate f(p1(n)),f(p2(n)),…,f(pn(n))f(p1(n)),f(p2(n)),…,f(pn(n)).
Input
The first line of the input contains two integers nn and mm (2≤n,m≤2⋅1052≤n,m≤2⋅105) — the number of elements in each permutation and the number of elements in xx.
The second line of the input contains mm integers (mm, not nn) x1,x2,…,xmx1,x2,…,xm (1≤xi≤n1≤xi≤n), where xixi is the ii-th element of xx. Elements of xx can repeat and appear in arbitrary order.
Output
Print nn integers: f(p1(n)),f(p2(n)),…,f(pn(n))f(p1(n)),f(p2(n)),…,f(pn(n)).
Examples
input
Copy
4 4 1 2 3 4
output
Copy
3 4 6 5
input
Copy
5 5 2 1 5 3 5
output
Copy
9 8 12 6 8
input
Copy
2 10 1 2 1 1 2 2 2 2 2 2
output
Copy
3 3
Note
Consider the first example:
x=[1,2,3,4], so
Consider the second example:
x=[2,1,5,3,5]x=[2,1,5,3,5], so
解题报告:看到这个题目确实有一丢丢的头疼,因为如果按照暴力去模拟的话,是有一定的困难的,因为需要不断地去更新数组,但是再卡了一天后,发现其实每次i数字的提前只是修改了1-n区间中某一段的值,对于题目我们要理解清楚我们要求的是什么,and这个pos(pi(n),x)代表的含义,就是值为x在i为第一位的n的数列中的位置,(可能这个描述的不是那么准确,只是确保这个函数的含义),然后我们最后求解的就是在第i的序列中,两两数字之间的距离的差值的绝对值之和。
思路:我们不确定可以直接去暴力模拟(虽然最后看别人是可以过的),但是还是在看了奆佬的思路后进行了差分的做法,我们知道在这n个序列中,任意的两个数字都可能存在位置的选择,假设我们选择了两个位置l,r,那么当我们进行到了第i个序列的时候,这两个位置的话就会根据i的大小拥有不同的贡献,最直观的是,
1.当i存在于位置1-l之间的时候,那么l和r对这个序列的贡献值就是r-l,
2.当i存在于l这个位置的时候,那么l和r对这个序列的贡献值就是r-1.
3.当i存在于l和r之间的时候,那么l和r对这个序列的贡献值就是r-l-1.
4当i存在于r这个位置的时候,那么l和r对这个序列的贡献值就是l.
5.当i存在于r+1和n之间的时候,那么对这个序列的贡献值就是r-l.
上述的情况是我们进行l和r这两个位置的贡献,对于各个序列,所以我们不需要去求解某一个序列的确切的值,我们只需要把这两个位置对于所有序列的贡献值进行一下差分处理就可以了。
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
int num[maxn];
ll f[maxn];
void modefy(int l,int r,int x)
{
f[l]+=x;
f[r+1]-=x;
}
int n,m;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d",&num[i]);
for(int i=1;i<=m-1;i++)
{
int l=num[i];
int r=num[i+1];
if(l==r)
continue;
if(l>r)
swap(l,r);
modefy(1,l-1,r-l);
modefy(l,l,r-1);
modefy(l+1,r-1,r-l-1);
modefy(r,r,l);
modefy(r+1,n,r-l);
}
for(int i=1;i<=n;i++)
{
f[i]+=f[i-1];
printf("%I64d ",f[i]);
}
printf("\n");
}