排列 题解(快速幂的思想)

排列

https://ac.nowcoder.com/acm/contest/7225/A

A 排列

做法,先建模,然后快速幂

m次反转为一次操作,第一次操作后的得到的数组为模式mode。

例如 mode=[3,2,1],其中mode[1]=3的含义为after[1]=before[3],即变换后数组的第1个位置存放原数组第3个位置的数。

操作之间满足交换率结合律,可以类比乘法计算,所以两次操作可以看作x*x,k次操作可以看作x^k。
在这种类比下,我们可以重定义乘号的意义,然后应用快速幂的思想。

重定义乘法
x,y是一个数组,代表操作模式,得到乘法定义如下
x*y代表在x的基础上进行y变换,具体做法如下

void cheng(int a[],int b[])//a*=b;
{
    for(int i=1;i<=n;i++)temp[i]=b[i];//防止a和b为同一数组时修改自身。
    for(int i=1;i<=n;i++)a[i]=temp[a[i]];
}

完整代码如下

#include <iostream>
using namespace std;
const int maxn=100005;
int ans[maxn],temp[maxn],mode[maxn];
int n,m,k;
void cheng(int a[],int b[])//a*=b;
{
    for(int i=1;i<=n;i++)temp[i]=b[i];//防止a=b的情况
    for(int i=1;i<=n;i++)a[i]=temp[a[i]];
}
void mypow(){
    int t=k;
    while(t){
        if(t&1)cheng(ans,mode);
        cheng(mode,mode);
        t>>=1;
    }
}
void init(){
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)ans[i]=mode[i]=i;
    int l,r;
    while(m--){
        cin>>l>>r;
        while(l<r){
            swap(mode[l++],mode[r--]);
        }
    }
}
int main(){
    init();
    mypow();
    for(int i=1;i<=n;i++)cout<<ans[i]<<' ';
    return 0;
}
全部评论

相关推荐

码农索隆:想看offer细节
点赞 评论 收藏
分享
07-28 16:37
门头沟学院 Java
哎,继续加油吧
ResourceUt...:能接到面试就已经是✌🏻了
腾讯一面2194人在聊
点赞 评论 收藏
分享
评论
5
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务