1. 程式人生 > 其它 >2020 CCPC Wannafly Winter Camp Day6 Div.1&2

2020 CCPC Wannafly Winter Camp Day6 Div.1&2

2020 CCPC Wannafly Winter Camp Day6 Div.1&2

比賽連結

2020 CCPC Wannafly Winter Camp Day6 Div.1&2

J-K重排列

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld

題目描述

對於一個排列 \({p[1...n]}\),我們設 \(p^{k}[i]=p[p^{k-1}[i]]\)p
k
[i]=p[p
k−1
[i]],且 p^{1}[i]=p[i]p
1
[i]=p[i]。
如果存在一個 {K}K,使得對於所有的 {i}i 都有 p^{K}[i]=ip
K
[i]=i,那麼 {K}K 就是 {p}p 的一個週期。
給定 {n,K}n,K,你需要計算有幾個 {1...n}1...n 的排列,滿足 {K}K 是它的一個週期
由於答案可能很大,你只需要輸出答案對 {998244353}998244353 取模後的值即可
輸入描述:
第一行一個整數 {T}T 表示資料組數
對於每組資料,第一行兩個正整數 {n,K}n,K
1\leq T\leq 1001≤T≤100,1\leq n\leq 501≤n≤50,1\leq K\leq 10^{18}1≤K≤10
18

輸出描述:
對於每組資料,輸出答案對 {998244353}998244353 取模後的值
示例1
輸入
複製
5
3 10
5 100
5 120
50 1000
1 1
輸出
複製
4
80
120
784037391
1

K-最大權值排列

題目描述

對於一個長度為 \({n}\) 的數列 \({A}\),定義它的權值 \({f(A)}\)為每一個區間平均數的和,即
\(\displaystyle f(A) = \sum_{i=1}^n \sum_{j=i}^n \frac{\sum_{k=i}^j A_k}{j-i+1}\)
現在給出了整數 \({n}\),你需要給出一個 \({1...n}\) 的排列 \({P}\)

使得 \({f(P)}\) 儘可能大。如果有多個不同的排列權值相同,則給出字典序最小的那個。
一個排列 \({a[1...n]}\) 的字典序比 \({b[1...n]}\) 的字典序小,當且僅當存在某個 \({j}\) 滿足 \({a[1...j-1]=b[1...j-1]}\)\({a[j]<b[j]}\)

輸入描述:

一行一個正整數 \(n~(1\le n \le 10^5)\).

輸出描述:

一行 \({n}\) 個數,表示答案的排列,行末需要由空格

輸入

5

輸出

1 3 5 4 2

解題思路

貪心

可以發現:中間出現的數的概率是最大的,所以,將大數放中間即可,由於要求字典序最小,所以,每次我們下標從 \(1\)

開始~

  • 時間複雜度:\(O(n)\)

程式碼

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    if(n&1)
    {
        for(int i=1;i<=n/2+1;i++)printf("%d ",2*i-1);
        for(int i=1;i<=n/2;i++)printf("%d ",n-1+(i-1)*(-2));
    }
    else
    {
        for(int i=1;i<=n/2;i++)printf("%d ",2*i-1);
        for(int i=1;i<=n/2;i++)printf("%d ",n+(i-1)*(-2));
    }
    return 0;
}