U - Obtain a Permutation CodeForces - 1294E

answer:

Note that no interaction between each column and each column, the greedy not determined a minimum operating value of, and then add up.

How did seek a minimum it? Maintain an array same representation in which same [i] = j represent the sequence of rolling up times have i j elements homing, then there will be no return nj a bit, so we have to modify them, modify nj times total, so a total of n -j + i times.

Therefore, the answer to each column of min (n-same [i] + i); Same on the method for finding. First, the range of each column element is the j <[i] = arr [j] <= n * m, and arr [i] [j]% m == j% m, i.e., the element value of each column m The value should be equal. Elements of the list is the only way.

For those who do not meet the condition of consideration. Because no matter how many times rollover, are unable to make it into place. For satisfying the condition assumed current position j, then the goal is to position POS. Then the answer to (j-pos + n)% n is the number of times of inversion. pos values: (arr [i] [j] -j) / m + 1;

So same [(j-pos + n)% n] ++;

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2E5+7;
vector<ll >ve[N];
ll same[N];//元素i向上移动same[j]个可以恢复
int main()
{
    ll n,m;
    cin>>n>>m;
    ll c=n*m;
    ll y;
    for(ll i=1;i<=c;i++){
        cin>>y;
        if(i%m==0){
            ve[m].push_back(y);
        }
        else ve[i%m].push_back(y);
    }
    ll sum=0;
    for(ll i=1;i<=m;i++){
        ll c=ve[i].size();
        for(ll j=0;j<c;j++){
            if(ve[i][j]<i||ve[i][j]>n*m) continue ;
            if(ve[i][j]%m==i%m){
                ll pos=(ve[i][j]-i)/m+1;
                ll k=(j+1-pos+n)%n;
                same[k]++;            }
        }
        ll cnt=n;
        for(ll j=0;j<n;j++){
            cnt=min(cnt,j+n-same[j]);
            same[j]=0;
        }
        sum+=cnt;
    }
    cout<<sum<<endl;
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/Accepting/p/12238997.html