排列
排列
https://ac.nowcoder.com/acm/contest/7225/A
快速幂思想
题目描述
牛牛拿到了一个长度为N的排列和M个区间,一开始排列是1、2、3......N。
然后他将这些区间在按顺序在排列上翻转,全部翻转一遍称一次操作。
现在他要去搞文化了...所以拜托你告诉他经过K次操作后的排列长什么样子。
题目分析
刚刚开始看题目的时候一脸懵逼,没看懂题目的意思,不过想想毕竟是第一题应该简单一些,所以就再次再次的看题目,发现:m次操作代表的是一次总的操作,也就是说要做k次m次的操作就是最终答案,但是题目给出的范围很大,所以需要用倍增的思想,倍增的思想能很快地实现计算,所以我们引进快速幂思想去分析题目
#include <bits/stdc++.h> using namespace std; const int maxn = 1e6 + 10; int ans[maxn], temp[maxn], mode[maxn]; int n, m, k; void solve(int a[], int 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 fastpow() { int t = k; while (t) { if (t & 1) solve(ans, mode); solve(mode, mode); t >>= 1; } } int main() { scanf("%d%d%d", &n, &m, &k); for (int i = 1; i <= n; ++i) ans[i] = mode[i] = i; int l, r; while (m--) { scanf("%d%d", &l, &r); while (l < r) swap(mode[l++], mode[r--]); } fastpow(); for (int i = 1; i <= n; ++i) printf("%d ", ans[i]); return 0; }
牛客比赛系列题解 文章被收录于专栏
加油加油