E - Modular Stability Educational Codeforces Round 88 (Rated for Div. 2)

题目链接:http://codeforces.com/contest/1359/problem/E

题目大意:

     给n和k,求有多少个不含重复元素的序列满足,任意排序之后对于任意整数从前到尾进行模运算结果都是相等的。

序列元素值在1-n之间。

题目思路:

       首先想到,当我们碰到那个最小的数字 , 假如说a_{min},那么之后的结果就都不会发生改变了。

       所以只考虑a_{min}之前的那些数,要满足什么条件,模完   a_{min-1}   再模 a_{min} , 结果相同呢。

       不妨我们先缩小问题:

               假如有两个数字,b  c  , 且b

    (x%b)%c  = (x % b)         设x = k_{1}*c+t  (k1 为 常数)  所以有   t % b  == (k_{1}*c+t)%b % b 

               得      t + k2 *b = (k1*c + t) + k3*b    (k1, k2 , k3 均为整数)

                         (k_{2}-k_{3})*b = k_{1}*c

   可见和 t 是无关的也就是对选择的x无关(真的吗?), 只和b,c关系有关  

 此时读者可能想,这个式子不是总是存在k1,k2,k3满足嘛?

 实际上不是的,我们只是把 t 消去了,但是k1和 t 是有关系的,也就是说当我们选定了一个x之后,k1 就确定了,也就是说选定x后,等式右边是个定值。但是k2和k3是我们可以自己确定的呀。

再结合题目对任意整数都要满足上式子的要求,所以k1不能是决定性因素,所以上式子成立,当且仅当 c % b = = 0

当序列所有值都是最小值的倍数的时候,序列合法。

#include
using namespace std;
typedef long long ll;
const int M=5e5+5;
const int mod=998244353;
ll fac[M],inv[M];
ll Pow(ll a,ll b){
    ll t=1ll;
    while(b){
        if(b&1)
            t=(t*a)%mod;
        b>>=1;
        a=(a*a)%mod;
    }
    return t;
}
ll C(int n,int m){
    return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main(){
{
    
    int n,k;
    cin>>n>>k;
    fac[0]=1;
    for(int i=1;i<=M-4;i++)
        fac[i]=1ll*fac[i-1]*i%mod;
    inv[n]=Pow(fac[n],mod-2);
    for(int i=n-1;i>=0;i--)
        inv[i]=1ll*inv[i+1]*(i+1)%mod;
    int ans=0;


    //cout<=k)
            ans=(ans+C(tmp,k-1))%mod;
    }
    cout<

 

你可能感兴趣的:(E - Modular Stability Educational Codeforces Round 88 (Rated for Div. 2))