【 Special Permutations】(codeforce1234E)(数学+差分数组)

题目:

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:

  • p1(4)=[1,2,3,4];
  • p2(4)=[2,1,3,4];
  • p3(4)=[3,1,2,4];
  • p4(4)=[4,1,2,3].

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

  • for the permutation p1(4)=[1,2,3,4] the answer is |1−2|+|2−3|+|3−4|=3|1−2|+|2−3|+|3−4|=3;
  • for the permutation p2(4)=[2,1,3,4] the answer is |2−1|+|1−3|+|3−4|=4|2−1|+|1−3|+|3−4|=4;
  • for the permutation p3(4)=[3,1,2,4] the answer is |2−3|+|3−1|+|1−4|=6|2−3|+|3−1|+|1−4|=6;
  • for the permutation p4(4)=[4,1,2,3] the answer is |2−3|+|3−4|+|4−1|=5|2−3|+|3−4|+|4−1|=5.

Consider the second example:

x=[2,1,5,3,5]x=[2,1,5,3,5], so

  • for the permutation p1(5)=[1,2,3,4,5] the answer is |2−1|+|1−5|+|5−3|+|3−5|=9|2−1|+|1−5|+|5−3|+|3−5|=9;
  • for the permutation p2(5)=[2,1,3,4,5] the answer is |1−2|+|2−5|+|5−3|+|3−5|=8|1−2|+|2−5|+|5−3|+|3−5|=8;
  • for the permutation p3(5)=[3,1,2,4,5] the answer is |3−2|+|2−5|+|5−1|+|1−5|=12|3−2|+|2−5|+|5−1|+|1−5|=12;
  • for the permutation p4(5)=[4,1,2,3,5] the answer is |3−2|+|2−5|+|5−4|+|4−5|=6|3−2|+|2−5|+|5−4|+|4−5|=6;
  • for the permutation p5(5)=[5,1,2,3,4] the answer is |3−2|+|2−1|+|1−4|+|4−1|=8|3−2|+|2−1|+|1−4|+|4−1|=8.

 

解题报告:看到这个题目确实有一丢丢的头疼,因为如果按照暴力去模拟的话,是有一定的困难的,因为需要不断地去更新数组,但是再卡了一天后,发现其实每次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<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
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");
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值