Codeforces 라운드 # 590 (사업부. 3) E. 특수 순열

링크 :

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;
}

추천

출처www.cnblogs.com/YDDDD/p/11619532.html