[Luo Gu P3322] SDOI2015 sort

Problem Description

A small there is arranged a 1-2 ^ N A [1..2 ^ N], that he wants to array A small to large, the operation may be performed with a small A N kinds, each operation may be performed at most once, for all

i (1 <= i <= N), operation is the i-th sequence from left to right is divided into 2 ^ {N-i + 1} segments, each segment contains exactly 2 ^ {i-1} number, then overall exchange in which two. A small wondered array A may be small to

Different sequence of operations in sorting a large number of small two different operation sequence A that, if and only if the number of different operations, or at least a different operation (or the operation of different types in different positions).

The following is an instance operation:

N=3,A[1..8]=[3,6,1,2,7,8,5,4].

The first operation of performing three operations, the exchange A [1..4] and A [5..8], the exchange of A [1..8] to [7,8,5,4,3, 6,1,2].

The second operation, the first type perform operations, the exchange A [3] and A [5], the exchange of A [1..8] as [7,8,3,4,5,6,1,2] .

The third operation is performed in the second operation, the exchange A [1..2] and A [7..8], the exchange of A [1..8] to [1,2,3,4,5, 6,7,8].

Input Format

The first row, a second row integer N, 2 ^ N integers, A [1..2 ^ N].

Output Format

An integer that represents the answer

Sample input

3
7 8 5 6 1 2 4 3

Sample Output

6

data range

100% of the data, 1 <= N <= 12.

Resolve

First, it is conceivable that the two blocks must be ordered per sort exchanged, we discuss each of small to large operation, if for the first \ (I \) modes of operation, the sequence of each length \ (2 ^ {i-1} \) block are ordered, then look at the length \ (2 ^ i \) a block which is not a monotonically increasing. If not requested number of blocks is greater than 2, no solution. Otherwise, if the number is 1, that the exchange block halves; in an amount of 2 to 4 divided portions of the two two exchange. As ordered judgment, it may be arranged in nature, if the value of the rightmost block by subtracting the leftmost block length equal described order.

Further, for a sequence of operations, the exchange of any two elements is not affected, so long as each found a \ (n-\) sequence of operations, should increase \ (n-! \) Scheme.

Code

#include <iostream>
#include <cstdio>
#define N 5000
using namespace std;
int n=1,m,i,a[N];
long long ans,f[N];
int read()
{
    char c=getchar();
    int w=0;
    while(c<'0'||c>'9') c=getchar();
    while(c<='9'&&c>='0'){
        w=w*10+c-'0';
        c=getchar();
    }
    return w;
}
void dfs(int x,int sum)
{
    int gap=(1<<(x-1)),gap1=gap<<1;
    for(int i=1;i<=n&&x>1;i+=gap){
        if(a[i+gap-1]-a[i]!=gap-1) return;
    }
    if(x==m+1){
        ans+=f[sum];
        return;
    }
    dfs(x+1,sum);
    int op[5],cnt=0;
    for(int i=1;i<=n;i+=gap1){
        int j=(2*i+gap1-1)/2+1;
        if(a[i+gap1-1]-a[i]!=gap1-1){
            op[++cnt]=i;
            op[++cnt]=j;
        }
    }
    if(cnt>4) return;
    for(int i=1;i<=cnt;i++){
        for(int j=i+1;j<=cnt;j++){
            for(int k=0;k<gap;k++) swap(a[op[i]+k],a[op[j]+k]);
            dfs(x+1,sum+1);
            for(int k=0;k<gap;k++) swap(a[op[i]+k],a[op[j]+k]);
        }
    }
}
int main()
{
    m=read();
    for(i=1;i<=m;i++) n*=2;
    f[0]=1;
    for(i=1;i<=12;i++) f[i]=f[i-1]*i;
    for(i=1;i<=n;i++) a[i]=read();
    dfs(1,0);
    printf("%lld\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/LSlzf/p/11873089.html