Codeforces Round #590 (Div. 3) E. Special Permutations

链接:

https://codeforces.com/contest/1234/problem/E

题意:

Let's define pi(n) as the following permutation: [i,1,2,…,i−1,i+1,…,n]. This means that the i-th permutation is almost identity (i.e. which maps every element to itself) permutation but the element i 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,…,xm (1≤xi≤n).

Let pos(p,val) be the position of the element val in p. 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)|, where |val| is the absolute value of val. This function means the sum of distances between adjacent elements of x in p.

Your task is to calculate f(p1(n)),f(p2(n)),…,f(pn(n)).

思路:

考虑对每个相邻的两个值, 在p上跨过所有点, 在移到前面的时候, 都会减一.
先计算, 每个值移到前面所造成的影响.
再记录每个值相邻的两个, 挨个计算.

代码:

#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