zoukankan      html  css  js  c++  java
  • [JLOI2016] 成绩比较

    题意:

    有n个人,m门课,每个人在每门课的得分是一个$[1,u_i ]$之间的整数。

    你知道自己在每门课的排名$r_i$,即有$r_i-1$个人得分高于你,$n-r_i$个人得分不高于你(不含自己)。

    求你恰好碾压k个人的方案数,a碾压b的含义为a每门课的得分都不低于b的得分。

    $n,mleq 100,u_i leq 10^{9}$。

    题解:

    一看到恰好k个就想到一个套路:$Num(恰好k个)=Num(钦定k个)-Num(钦定k+1个)+cdots$。

    此时我们要考虑到一个严重的问题:(以下为防止组合数越界有做简单变式)

    这题从n-1个人里选x个被碾压的方案数到底是${n-1}choose {n-1-x}$还是${{n-1} choose {n-1-k}}{{n-1-k}choose {n-1-x}}$?

    首先回顾一下${n}choose x$和${{n} choose m}{mchoose x}$的本质区别:前者是分两个集合,后者是分三个集合。

    也就是说对于每个大小为x的集合S,前者只被算了一遍,后者被算了${n-x}choose{m-x}$遍。

    那么我们考虑这道题容斥的底层过程:有两个大小为k的集合S1和S2,它们的并集是大小为k+1的S3。

    那S3是被算了一遍还是被算了${{k+1}choose{k}}$遍呢?显然是后者,于是一开始就应该用后者计算。

    (upd:另一种解释:是对于每个集合容斥而不是对于集合大小容斥,所以每次必须钦定k个不动。)

    回到容斥,答案就是

    ${n-1choose {n-1-k}}sum limits_{j=k}^{n-1}{(-1)^{j-k}{n-1-kchoose {n-1-j}}prod limits_{i=1}^{m}{n-1-jchoose n-r_i -j}sum limits_{x=1}^{u_i}{x^{n-r_i}(u_i -x)^{r_i -1}}}$

    最后面那个式子可以用二项式定理拆一下,我是在容斥里面写了个子容斥。(所以说我nt呢)

    大概形如

    ${n-1choose {n-1-k}}sum limits_{j=k}^{n-1}{(-1)^{j-k}{n-1-kchoose {n-1-j}}prod limits_{i=1}^{m}{n-1-jchoose n-r_i -j}sum limits_{x=1}^{u_i}{x^{n-r_i}(u_i -x)^{r_i -1}}}$

    $={n-1choose {n-1-k}}sum limits_{j=k}^{n-1}{(-1)^{j-k}{n-1-kchoose {n-1-j}}prod limits_{i=1}^{m}{n-1-jchoose n-r_i -j}sum limits_{l=n-r_i}^{n-1}{(-1)^{l-(n-r_i )}{r_i -1choose n-1-l}u_{i}^{n-1-l}sum limits_{x=1}^{u_i}x^{l}}}$

    考虑原式的组合意义不难得到该容斥,最后那个式子直接拉格朗日插值出来就好了。

    复杂度$O(mn^{3})$。上界为预处理插值,可以优化到$O(mn^{2})$,不过……

    套路:

    • 形如$Num(恰好k个)=Num(钦定k个)-Num(钦定k+1个)+cdots$的容斥$ ightarrow$每个大小为k+1的集合被计算$k+1choose k$次。(大部分时候k为0所以区别不开)
    • 容斥时:注意区分对集合容斥和对集合大小容斥的区别。

    代码:

    #include<bits/stdc++.h>
    #define maxn 205
    #define maxm 500005
    #define inf 0x7fffffff
    #define mod 1000000007
    #define ll long long
    #define rint register ll
    #define debug(x) cerr<<#x<<": "<<x<<endl
    #define fgx cerr<<"--------------"<<endl
    #define dgx cerr<<"=============="<<endl
    
    using namespace std;
    struct node{ll x,y;}tp[maxn];
    ll C[maxn][maxn],inv[maxn],R[maxn],U[maxn],L[maxn][maxn]; 
    
    inline ll read(){
        ll x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    
    inline ll pw(ll a,ll b){ll r=1;while(b)r=(b&1)?r*a%mod:r,a=a*a%mod,b>>=1;return r;}
    inline void init(ll n){
        C[0][0]=1;
        for(ll i=1;i<=n;i++){
            C[i][0]=1;
            for(ll j=1;j<=i;j++)
                C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
        }
    }
    inline ll Lagrange(ll x,ll n){
        for(ll i=1;i<=n+2;i++)
            tp[i].x=i,tp[i].y=(tp[i-1].y+pw(i,n))%mod;
        for(ll i=-n-2;i<=n+2;i++)
            inv[i+n+2]=pw((i+mod)%mod,mod-2);
        ll ans=0;
        for(ll i=1;i<=n+2;i++){
            ll res=tp[i].y;
            for(ll j=1;j<=n+2;j++){
                if(j==i) continue;
                res=res*(x-tp[j].x+mod)%mod*inv[tp[i].x-tp[j].x+n+2]%mod;
            }
            ans=(ans+res)%mod;
        }
        return ans;
    }
    
    int main(){
        ll n=read(),m=read(),K=read(),mn=inf;
        for(ll i=1;i<=m;i++) U[i]=read();
        for(ll i=1;i<=m;i++) R[i]=read(),mn=min(n-R[i],mn);
        init(n); ll ans=0;
        for(ll i=1;i<=m;i++)
            for(ll j=0;j<=n-1;j++){
                if(j==0) L[i][j]=U[i];
                else L[i][j]=Lagrange(U[i],j);
            }
        for(ll k=K,t1=1;k<=mn;k++,t1=t1*(mod-1)%mod){
            ll r1=1;
            for(ll i=1;i<=m;i++){
                ll t=n-R[i],r2=0;
                for(ll j=t,t2=1;j<=n-1;j++,t2=t2*(mod-1)%mod)
                    r2=(r2+t2*C[n-1-t][n-1-j]%mod*pw(U[i],n-1-j)%mod*L[i][j]%mod)%mod;
                r1=r1*r2%mod*C[n-1-k][t-k]%mod;
            }
            ans=(ans+r1*t1%mod*C[n-1-K][n-1-k]%mod)%mod;
        }
        printf("%lld
    ",ans*C[n-1][K]%mod);
        return 0;
    }
    成绩比较
  • 相关阅读:
    51-maven私有库神坑之:“Downloading: http://repo.maven.apache.org/maven2/”
    50-maven 仓库配置
    49-2017年第八届蓝桥杯国赛试题及详解(Java本科B组)
    21-matlab 迷宫题
    20-matlab全排列-函数调用
    52-python 画图二维
    51-python3 pandas读写excel
    48-设置tomcat虚拟路径的两种方法(Eclipse、tomcat、IDEA)
    19-matlab知识点复习二
    【剑指offer】二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/YSFAC/p/13290090.html
Copyright © 2011-2022 走看看