Codeforces Round #176 (Div. 2) D. Shifting(模拟,STLdeque应用)
2017-02-22 15:35
411 查看
题目链接
D. Shifting
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
John Doe has found the beautiful permutation formula.
Let's take permutation p = p1, p2, ..., pn.
Let's define transformation f of this permutation:
where k (k > 1) is
an integer, the transformation parameter, r is such maximum integer that rk ≤ n.
If rk = n, then elements prk + 1, prk + 2and
so on are omitted. In other words, the described transformation of permutation p cyclically shifts to the left each consecutive block
of length k and the last block with the length equal to the remainder after dividing n by k.
John Doe thinks that permutation f(f( ... f(p = [1, 2, ..., n], 2) ... , n - 1), n) is
beautiful. Unfortunately, he cannot quickly find the beautiful permutation he's interested in. That's why he asked you to help him.
Your task is to find a beautiful permutation for the given n. For clarifications, see the notes to the third sample.
Input
A single line contains integer n (2 ≤ n ≤ 106).
Output
Print n distinct space-separated integers from 1 to n —
a beautiful permutation of size n.
Examples
input
output
input
output
input
output
Note
A note to the third test sample:
f([1, 2, 3, 4], 2) = [2, 1, 4, 3]
f([2, 1, 4, 3], 3) = [1, 4, 2, 3]
f([1, 4, 2, 3], 4) = [4, 2, 3, 1]
题意:
定义排列p = p1, p2, ..., pn。
定义函数f(p, k)用来转换p排列,k是转换参数, k > 1。
假设排列p的长度为n,首先把p按长度k进行分块,若最后一块长度不足k,则其长度为n%k,然后分别对每一块循环左移一位,得到一个新的排列。
给定n(2 <= n <= 1e6)。请输出 f(f(...f(p = [1,2,...,n],2)...,n-1,),n)的结果。
对于样例3:
1.f([1,2,3,4],2) = [2,1,4,3]
2.f([2,1,4,3],3) = [1,4,2,3]
3.f([1,4,2,3],4) = [4,2,3,1]
题解:
对f(p,k)循环右移一位之后可以发现得到的序列相当于对原序列中下标mod k=1位置构成的子序列循环右移一位,
因此只需要对这些位置循环右移一位再将整个序列循环左移一位(也就是把第一个数字挪到最后)即可得到f(p,k),
可以用一个双端队列维护,第k次操作需要操作n/k+O(1)的元素,总复杂度是O(nlogn)。
quailty代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<deque>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const int inf=0x3fffffff;
const ll mod=1000000007;
const int maxn=20+10;
deque<int> dq;
int main()
{
int n;
scanf("%d",&n);
rep(i,1,n+1) dq.push_back(i);
rep(i,2,n+1)
{
for(int j=(n-1)/i;j>0;j--)
swap(dq[(j-1)*i],dq[j*i]);
dq.push_back(dq.front());
dq.pop_front();
}
rep(i,0,n) printf("%d ",dq[i]);
return 0;
}
D. Shifting
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
John Doe has found the beautiful permutation formula.
Let's take permutation p = p1, p2, ..., pn.
Let's define transformation f of this permutation:
where k (k > 1) is
an integer, the transformation parameter, r is such maximum integer that rk ≤ n.
If rk = n, then elements prk + 1, prk + 2and
so on are omitted. In other words, the described transformation of permutation p cyclically shifts to the left each consecutive block
of length k and the last block with the length equal to the remainder after dividing n by k.
John Doe thinks that permutation f(f( ... f(p = [1, 2, ..., n], 2) ... , n - 1), n) is
beautiful. Unfortunately, he cannot quickly find the beautiful permutation he's interested in. That's why he asked you to help him.
Your task is to find a beautiful permutation for the given n. For clarifications, see the notes to the third sample.
Input
A single line contains integer n (2 ≤ n ≤ 106).
Output
Print n distinct space-separated integers from 1 to n —
a beautiful permutation of size n.
Examples
input
2
output
2 1
input
3
output
1 3 2
input
4
output
4 2 3 1
Note
A note to the third test sample:
f([1, 2, 3, 4], 2) = [2, 1, 4, 3]
f([2, 1, 4, 3], 3) = [1, 4, 2, 3]
f([1, 4, 2, 3], 4) = [4, 2, 3, 1]
题意:
定义排列p = p1, p2, ..., pn。
定义函数f(p, k)用来转换p排列,k是转换参数, k > 1。
假设排列p的长度为n,首先把p按长度k进行分块,若最后一块长度不足k,则其长度为n%k,然后分别对每一块循环左移一位,得到一个新的排列。
给定n(2 <= n <= 1e6)。请输出 f(f(...f(p = [1,2,...,n],2)...,n-1,),n)的结果。
对于样例3:
1.f([1,2,3,4],2) = [2,1,4,3]
2.f([2,1,4,3],3) = [1,4,2,3]
3.f([1,4,2,3],4) = [4,2,3,1]
题解:
对f(p,k)循环右移一位之后可以发现得到的序列相当于对原序列中下标mod k=1位置构成的子序列循环右移一位,
因此只需要对这些位置循环右移一位再将整个序列循环左移一位(也就是把第一个数字挪到最后)即可得到f(p,k),
可以用一个双端队列维护,第k次操作需要操作n/k+O(1)的元素,总复杂度是O(nlogn)。
quailty代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<deque>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const int inf=0x3fffffff;
const ll mod=1000000007;
const int maxn=20+10;
deque<int> dq;
int main()
{
int n;
scanf("%d",&n);
rep(i,1,n+1) dq.push_back(i);
rep(i,2,n+1)
{
for(int j=(n-1)/i;j>0;j--)
swap(dq[(j-1)*i],dq[j*i]);
dq.push_back(dq.front());
dq.pop_front();
}
rep(i,0,n) printf("%d ",dq[i]);
return 0;
}
相关文章推荐
- div+css布局的应用
- 用div和span模拟select控件
- Java模拟POST表单操作 HttpClient的应用及注意事项
- javascript用div模拟Alert警告框,渐变弹出。兼容IE,firefox
- php curl函数应用方法之模拟浏览器
- js 可拖动alert的div模拟层
- CSS学习笔记-附加篇(div中class与id的区别及应用)
- JavaScript 用DIV模拟弹出窗口并跟随窗体滚动
- 用Jquery模拟的div-css.com中的JS特效
- 简单易行--利用web现有DIV元素模拟滚动条.
- XHTML中的表格应用及表格的模拟
- div+css详解定位与定位应用
- java 模拟 POST表单操作 HTTPCLIENT的应用 及注意事项
- 可编辑Select下拉列表控件实现方法(非DIV模拟)
- 使用" 参数化基类" 和" 成员函数指针" 模拟实现虚函数--在实际中的应用
- --------- div的应用 根据select 的值 来显示多少个select ---------
- Windows下的wap应用,手机模拟测试工具
- 用DIV模拟弹出窗口--窗体滚动跟随--丁学
- Behavior模型应用:可拖动的div容器
- div+css布局的应用