列表

详情


NC206067. 排列

描述

牛牛拿到了一个长度为N的排列和M个区间,一开始排列是1、2、3......N。
然后他将这些区间在按顺序在排列上翻转,全部翻转一遍称一次操作。
现在他要去搞文化了...所以拜托你告诉他经过K次操作后的排列长什么样子。

输入描述

第一行三个整数:N,M,K。
接下来M行,每行两个整数L和R描述一个区间。

输出描述

输出一行N个数,表示经过K次操作后的排列。

示例1

输入:

5 2 2
1 4
2 3

输出:

1 2 3 4 5

说明:

排列1 2 3 4 5中,区间[1 , 4]和[2 , 3]翻转后,排列为4 2 3 1 5。
再操作一次,则为1 2 3 4 5。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 42ms, 内存消耗: 13444K, 提交时间: 2020-09-09 09:59:47

#include<bits/stdc++.h>
using namespace std;
#define rep(i,x,y) for(int i=x;i<=y;i++)

int n,m,k;
const int N=1e5+1;
int a[N];
int f[N][31];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cin>>n>>m>>k;
    rep(i,1,n)a[i]=i;
    rep(i,1,m){int l,r;cin>>l>>r;reverse(a+l,a+r+1);}
    rep(i,1,n)f[i][0]=a[i];
    rep(j,1,30)rep(i,1,n)f[i][j]=f[f[i][j-1]][j-1];
    rep(i,1,n){
        int now=i;
        rep(j,0,30)if(k>>j&1)now=f[now][j];
        cout<<now<<' ';
    }
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 37ms, 内存消耗: 13444K, 提交时间: 2020-09-05 18:03:57

#include<bits/stdc++.h>
using namespace std;
#define rep(i,x,y) for(int i=x;i<=y;i++)

int n,m,k;
const int N=1e5+1;
int a[N];
int f[N][31];
int main(){
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cin>>n>>m>>k;
	rep(i,1,n)a[i]=i;
	rep(i,1,m){int l,r;cin>>l>>r;reverse(a+l,a+r+1);}
	rep(i,1,n)f[i][0]=a[i];
	rep(j,1,30)rep(i,1,n)f[i][j]=f[f[i][j-1]][j-1];
	rep(i,1,n){
		int now=i;
		rep(j,0,30)if(k>>j&1)now=f[now][j];
		cout<<now<<' ';
	}
	return 0;
}

上一题