1. 程式人生 > >upc 6617: Finite Encyclopedia of Integer Sequences(樹的先序遍歷第n/2個結點)

upc 6617: Finite Encyclopedia of Integer Sequences(樹的先序遍歷第n/2個結點)

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;
}