6617: Finite Encyclopedia of Integer Sequences
时间限制: 1 Sec 内存限制: 128 MB
提交: 239 解决: 42
[提交] [状态] [讨论版] [命题人:admin]
题目描述
In Finite Encyclopedia of Integer Sequences (FEIS), all integer sequences of lengths between 1 and N (inclusive) consisting of integers between 1 and K (inclusive) are listed.
Let the total number of sequences listed in FEIS be X. Among those sequences, find the (X⁄2)-th (rounded up to the nearest integer) lexicographically smallest one.
Constraints
1≤N,K≤3×105
N and K are integers.
输入
Input is given from Standard Input in the following format:
K N
输出
Print the (X⁄2)-th (rounded up to the nearest integer) lexicographically smallest sequence listed in FEIS, with spaces in between, where X is the total number of sequences listed in FEIS.
样例输入
3 2
样例输出
2 1
提示
There are 12 sequences listed in FEIS: (1),(1,1),(1,2),(1,3),(2),(2,1),(2,2),(2,3),(3),(3,1),(3,2),(3,3). The (12⁄2=6)-th lexicographically smallest one among them is (2,1).
【小结】
本来用dfs直接模拟树,几乎20以内的数我都和暴力程序对比了,没有错,可为什么就是一直WA+WA+WA?赛后跟彬子哥的代码对拍,拍了十几秒吧,我都要说这个他妈对拍都拍不出来。啪,一个错误数据蹦出来了,3 88。这是一组杀人的数据,我的输出和答案正好差1。又多拍了几组,都是差1~ 无语,几乎90%的数据都对。 或许罪魁祸首是那个n/2向上取整,某一个瞬间,我的代码没取上去吧。。。。。自闭了。
【分析】
对于k是偶数时,很容易发现,答案为 k/2 k k k .... k,共n个数。
k是奇数时,应该很靠近中间,即(k+1)/2 (k+1)/2 (k+1)/2.....而多写几组会发现,真是答案会和这个序列在题意要求下,正好相差n/2个字典序。让这个序列按照树的先序遍历往前退n/2步即为正确答案。
【代码】
/****
***author: winter2121
****/
#include<bits/stdc++.h>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define SI(i) scanf("%d",&i)
#define PI(i) printf("%d\n",i)
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int MAX=3e5+5;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
int dir[9][2]={0,1,0,-1,1,0,-1,0, -1,-1,-1,1,1,-1,1,1};
template<class T>bool gmax(T &a,T b){return a<b?a=b,1:0;}
template<class T>bool gmin(T &a,T b){return a>b?a=b,1:0;}
template<class T>void gmod(T &a,T b){a=(a%mod+b)%mod;}
ll gcd(ll a,ll b){ while(b) b^=a^=b^=a%=b; return a;}
ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
ll qpow(ll n,ll m)
{
n%=mod;
ll ans=1;
while(m)
{
if(m%2)ans=(ans*n)%mod;
m>>=1; n=(n*n)%mod;
}
return ans;
}
int a[MAX];
int main()
{
int n,k,rem,p;
while(cin>>k>>n)
{
p=n;
if(k%2==0)
{
rep(i,2,n)a[i]=k;
a[1]=k/2;
}
else
{
rep(i,1,n)a[i]=(k+1)/2;
rem=n/2,p=n;
while(rem--) //按字典序往后退
{
if(a[p]==1)a[p--]--; //向上退
else
{
a[p]--;
while(p<n)a[++p]=k; //回退到了上一课子树,并直接到底
}
}
}
rep(i,1,p)printf("%d%c",a[i],i<p?' ':'\n');
}
return 0;
}