링크 :
https://codeforces.com/contest/1234/problem/E
질문의 의미 :
이제 다음과 같이 순열 PI (N)을 정의 할 수 : [I, 1,2, ..., I-1, I + 1, ..., N]. 이는 i 번째 순열 신원 거의인지 (즉, 자체의 모든 요소에 매핑하는) 치환을 의미하지만, 요소 i는 최초의 위치에있다. 예를 들면 :
P1 (4) = [1,2,3,4];
P2 (4) = [2,1,3,4];
P3 (4) = [3,1,2,4];
P4 (4) = [4,1,2,3].
당신은 배열 X1, X2, ..., XM (1≤xi≤n를) 제공됩니다.
하자 POS (p, 발)는 P의 요소 발 위치 될. 따라서, POS (P1 (4), 3) = 3, POS (P2 (4), 2) = 1, POS (P4 (4), 4) = 1.
POS (p, XI) -pos (p, XI + 1) | |, | 발의은 함수 f (P) = Σi = 1m-1을 정의 할 | 발의 절대 값이다. 이 함수 P X에 인접하는 요소 사이의 거리의 합을 의미한다.
당신의 작업은 F (P1 (N)), f를 계산하는 것이다 (P2 (n)를), ..., F (PN (N)).
아이디어 :
전방으로 이동 한만큼 감소되는 페이지상의 모든 점을 사이에두고 인접하는 2 개 개의 값을 고려한.
먼저 계산 값은 각각 이전 영향으로 인해 이동한다.
재기록 값마다 인접한 두 번 계산 하나.
코드 :
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 2e5+10;
int a[MAXN], cnt[MAXN];
LL res[MAXN];
vector<int> vec[MAXN];
int n, m;
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1;i <= m;i++)
scanf("%d", &a[i]);
for (int i = 1;i < m;i++)
res[1] += abs(a[i]-a[i+1]);
for (int i = 1;i < m;i++)
{
int l = a[i], r = a[i + 1];
if (l == r)
continue;
vec[l].push_back(r);
vec[r].push_back(l);
if (l > r)
swap(l, r);
if (r - l < 2)
continue;
cnt[l + 1]++;
cnt[r]--;
}
for (int i = 1;i < n;i++)
cnt[i+1] += cnt[i];
for (int i = 2;i <= n;i++)
{
res[i] = res[1]-cnt[i];
for (auto x: vec[i])
{
res[i] -= abs(i-x);
res[i] += x-1+(x<i);
}
}
for (int i = 1;i <= n;i++)
printf("%I64d ", res[i]);
return 0;
}