zoukankan      html  css  js  c++  java
  • P3270 [JLOI2016]成绩比较(拉格朗日插值)

    传送门

    挺神仙的啊……

    (f[i][j])为考虑前(i)门课程,有(j)个人被(B)爷碾压的方案数,那么转移为$$f[i][j]=sum_{k=j}^{n-1}f[i-1][k] imes {k choose k-j} imes {n-1-k choose r[i]-1-(k-j)} imes g(i)$$
    解释一下,就是考虑第(i)门课,枚举在这之前分比(B)爷高的人数(k),要从中选出(k-j)个使得他们这一门课的分数比(B)爷高,然后在剩下的(n-1-k)个人里选出(r[i]-1-(k-j))个人使他们比(B)爷分数高

    最后的(g(i))表示对于第(i)门课程,把(1)(u[i])的分数分给(n-1)个人使得他们中比(B)爷分数高的人数为(r[i])的方案数

    可以枚举(B)爷的分数,得$$g[i]=sum_{k=1}^{u_i}k^{n-r[i]}(u_i-k)^{r[i]-1}$$
    然而(u_i)太大不好直接算,发现后面那东西是一个多项式,且多项式的次数为(n-1),所以可以用拉格朗日插值快速计算

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=155,P=1e9+7;
    inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R int y){
        R int res=1;
        for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
        return res;
    }
    int C[N][N],f[N][N],u[N],r[N],g[N];
    int n,m,k;
    int Large(int d,int r){
    	fp(i,0,n){
    		g[i]=0;
    		fp(j,1,i)g[i]=add(g[i],1ll*ksm(j,n-r)*ksm(i-j,r-1)%P);
    	}if(d<=n)return g[d];
    	int res=0,ty=(n&1)?P-1:1,tmp=1;
    	fp(i,1,n)tmp=1ll*tmp*(d-i)%P*ksm(i,P-2)%P;
    	fp(i,0,n){
    		res=add(res,1ll*g[i]*ty%P*tmp%P);
    		tmp=1ll*tmp*(d-i)%P*ksm(d-i-1,P-2)%P*(n-i)%P*ksm(i+1,P-2)%P;
    		ty=P-ty;
    	}return res;
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),m=read(),k=read();
    	fp(i,1,m)u[i]=read();
    	fp(i,1,m)r[i]=read();
    	fp(i,0,N-5){
    		C[i][0]=1;
    		fp(j,1,i)C[i][j]=add(C[i-1][j],C[i-1][j-1]);
    	}
    	f[0][n-1]=1;
    	fp(i,1,m){
    		int res=Large(u[i],r[i]);
    		fp(j,k,n-1){
    			fp(l,j,n-1)if(l-j<=r[i]-1)
    				f[i][j]=add(f[i][j],1ll*f[i-1][l]*C[l][l-j]%P*C[n-1-l][r[i]-1-(l-j)]%P);
    			f[i][j]=mul(f[i][j],res);
    		}
    	}printf("%d
    ",f[m][k]);return 0;
    }
    
  • 相关阅读:
    CentOS-7 虚拟机意外断电后的数据恢复
    CentOS7 搭建VNC 服务
    CentOS7-ulimit
    CentOS-7 初始化配置
    Centos Bond设置实例
    服务检测脚本
    sshd服务
    input常用属性
    前端工具-Sublime、WebStorm-快捷方式使用
    随机抽选效果、随机抽选红色球
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10217322.html
Copyright © 2011-2022 走看看