Niu Ke Challenge 39 E Niu Niu and Sequence Solutions

1. Chat

This competition is really miserable. My data block for question B was blocked, only 75 points qwq, and the block and line tree for question C were blocked. I'm so hard. . .

Then, I looked at question D, and emmm counted the next question. At first, I looked at question E, wow number thesis, so I started working on the draft paper. . .

2. Problem Solution

The title asks you to find a sequence of length n, and the sequence element is an integer of [1, k], and there are two sequences of strictly rising and strictly falling positions at the same time.

At the beginning, I planned to do it directly and found it very difficult to do. . . We will do the opposite

Ans = the number of all schemes-the number of sequences that have strict rises and strict declines at the same time

Note that the number of all schemes is \ (k ^ n \) , this can be run directly over the card speed meter

Then, we are asking for the next section.

We have found that the sequence of strictly rising and falling at the same time must satisfy:

对于\(\forall i\in[2,n]a_i<=a_{i-1}或者\forall i\in[2,n]a_i>=a_{i-1}\)

Then, we only need to count these two.

Note that in these two schemes, the reverse order of one of them must satisfy the other, so we only need to request the number x of one scheme, and the number of schemes of the other must also be x, but when all When \ (a_i \) takes the same value, it will satisfy two sequences at the same time, so the sum of the two schemes should be reduced by k

Now is how to find one of them

At the beginning, I didn't want to count, just hit a set of tables:

n        k        ans
2        1        1        C(2,2)
2        2        3        C(3,2)
2        3        6        C(4,2)
2        4        10       C(5,2)
3        1        1        C(3,3)
3        2        4        C(4,3)
3        3        10       C(5,3)
3        4        20       C(6,3)
4        1        1        C(4,4)
4        2        5        C(5,4)
4        3        15       C(6,4)
4        4        35       C(7,4)

After observation, it is found that this is not a k-dimensional prefix and a regular number of combinations?

Looking for the rule, you will find that the number of solutions is equal to C (n + k-1, n) = C (n + k-1, k-1)

Let us understand the meaning of the following formula:

Now we are seeking n number of schemes that satisfy the n numbers that all belong to \ ([1, k] \) and are strictly not falling (or strictly not rising)

In fact, the meaning of the formula is equivalent, we first dig n + k-1 empty, and then select k-1 empty from these empty as "separator"

Fill 1 between the beginning and the first partition, and fill 2 from the first partition to the second partition. . . Fill k between the k-1th partition and the end

In this way, we have successfully obtained a number of programs with length n (the remaining n empty fillers), strictly not falling (the number of fillers in each partition segment increases sequentially). (Since the two partitions may be adjacent, there are some numbers that are not filled in, so all plans are included)

Now let's solve the problem

First we convert to the formula form:

\ (Ans = \ frac {(n + k-1)!} {N! * (K-1)!} \)

Approximately:

\(Ans=\frac{\prod_{i=n+1}^{n+k-1}i}{(k-1)!}\)

The scope of the question: \ (k <= 10 ^ 6, \ sum k <= 3 * 10 ^ 7 \)

Therefore, we directly preprocess O (n) to preprocess the inverse of the factorial of 1-10 ^ 6 \) and then calculate the numerator of the answer violently at each query, and finally process the answer directly

Code:

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353,N=1e6+1;
int n,k;
int ni[N],sp[N];
inline int ksm(int x,int y){
    int ans=1;
    while(y){
        if(y&1){
            ans=(1LL*ans*x)%mod;
        }
        x=(1LL*x*x)%mod;
        y>>=1;
    }
    return ans%mod;
}
int main(){
    ni[1]=1,sp[0]=sp[1]=1;
    for(int i=2;i<N;++i){
        ni[i]=(1LL*ni[mod%i]*(mod-mod/i))%mod;
        sp[i]=(1LL*sp[i-1]*ni[i])%mod;
    }
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&k);
        if(k==1){//特判1
            puts("0");
            continue;
        }
        int tot=ksm(k,n);
        tot=(tot+k)%mod;
        int kil;
        if(k==2){
            kil=(n+1)%mod;
        }else{
            long long X=k+(n-1),Y=n;
            kil=1;
            for(int i=Y+1;i<=X;++i){
                kil=(1LL*kil*i)%mod;
            }
            kil=(1LL*kil*sp[k-1])%mod;
        }
        tot-=(kil*2)%mod;
        tot=(tot%mod+mod)%mod;
        printf("%d\n",tot);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/ThinkofBlank/p/12724541.html