找最小的k個數(優先佇列)

黑碼發表於2017-06-12

kkun的一道簡單簽到題
釋出時間: 2017年6月11日 17:59 最後更新: 2017年6月11日 18:10 時間限制: 2000ms 記憶體限制: 512M

描述
青大最優雅的程式設計師kkun一直友好(?)的致力於為學妹們出一道做法優雅而且非常簡單的題。

例如著名的“一道非常簡單的爐石題”,“一道非常簡單的簽到題”,“一道非常簡單的數學題”,“一道非常簡單的平衡樹套替罪羊樹套喜羊羊樹套聖誕樹套動態仙人掌”,“一道非常簡單的簽到題”(這個人是真的優雅,比那個菜凡不知道高到哪裡去了!)

這次也不例外,他想從no cer那裡拿到n個數,並找到其中最小的k個數。

但是no cer只是扔給了他一個公式:val[i]=k^(i+1)%1000000007(1<=i<=n),並讓他自己一邊玩去。

kkun頓時覺得這個問題變得索然無味,所以他讓你來解決這個問題。

最終從大到小輸出最小的k個數。

輸入
第一行一個整數t代表資料組數
每組資料中
第一行兩個整數n,k
n<=1e7
k<=1e4
k<=n

輸出
從大到小輸出k個數,每組資料佔一行

樣例輸入1 複製
1
3 2
樣例輸出1
8 4

沒看這題。= =一個優先佇列

#include <bits/stdc++.h>
using namespace std;
const int N = 1e7+100;
typedef long long ll;
ll a[N];
const int mod = 1e9+7;


int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        priority_queue<int> Q;
        a[0]=m;
        for(int i=1;i<=n;i++)
        {            
            a[i]=a[i-1]*m%mod;
            if(i<=m)
                Q.push(a[i]);
        }

        for(int i=m+1;i<=n;i++)
        {
            int top=Q.top();
            if(a[i]<top)
            {
                Q.pop();
                Q.push(a[i]);
            }
        }
        printf("%d",Q.top() );
        Q.pop();
        for(int i=1;i<m;i++)
        {
            printf(" %d",Q.top() );
            Q.pop();
        }
        printf("\n");
    }
}

相關文章