zoukankan      html  css  js  c++  java
  • 洛谷 P4478 [BJWC2018]上学路线

    洛谷 P4478 [BJWC2018]上学路线


    原题

    神仙题orz,竟然没有1A。。。。容斥+卢卡斯+crt??

    首先用容斥做,记(f[i][0/1])表示到i号点经过了奇数/偶数个点的方案数,因为(f[i][0]+f[i][1]=1)所以只要记一个(f[i])是经过奇数个点的方案数就行

    枚举一个左下的点走到这个点,或者直接从1走到这个点,

    (f[i]=sum_{ ext{j in lower left side}}((1-f[j]) imes C_{x_i+y_i-x_j-y_j}^{x_i-x_j})+C_{x_i+y_i}^{x_i})

    答案就是从所有点走到这个点,加上从1号点走到这个点(sum_{i}((1-f[i]) imes C_{n+m-x_i-x_j}^{n-x_i})+C_{n+m}^{n})

    sort一遍dp就做完了,只剩下求组合数了

    模数好像不是质数,分解一下发现是3×5×6793×10007

    crt即可,对每个模数求一遍方案,求组合数用lucas

    lucas大概就是(C_{n}^{m} ext{mod }p=C_{lfloorfrac{n}{p} floor}^{{lfloorfrac{m}{p} floor}} imes C_{n ext{ mod }p}^{m ext{ mod }p}mod p)

    这神仙题就做完了。。。

    #include<bits/stdc++.h>
    #define il inline
    #define vd void
    typedef long long ll;
    il ll gi(){
    	ll x=0;
    	char ch=getchar();
    	while(!isdigit(ch))ch=getchar();
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return x;
    }
    ll mod;
    struct yyb{ll x,y;}a[210];
    il bool cmp(const yyb&a,const yyb&b){
    	if(a.x^b.x)return a.x<b.x;
    	return a.y<b.y;
    }
    ll f[210];
    ll p[5],tot;
    ll Ans[5];
    ll pp[5],tt[5];
    ll fact[1000010],inv[1000010];
    il ll C(ll n,ll m,ll P){
    	if(n<m)return 0;
    	return fact[n]*inv[fact[m]*fact[n-m]%P]%P;
    }
    il ll Lucas(ll n,ll m,ll P){
    	if(n<m)return 0;if(!n)return 1;
    	return Lucas(n/P,m/P,P)*C(n%P,m%P,P)%P;
    }
    int main(){
    #ifndef ONLINE_JUDGE
    	freopen("4478.in","r",stdin);
    	freopen("4478.out","w",stdout);
    #endif
    	ll n=gi(),m=gi(),t=gi();mod=gi();
    	if(mod==1000003)p[tot=1]=mod;
    	else p[++tot]=3,p[++tot]=5,p[++tot]=6793,p[++tot]=10007;
    	for(int i=1;i<=t;++i)a[i].x=gi(),a[i].y=gi();
    	std::sort(a+1,a+t+1,cmp);
    	ll M=1;
    	for(int i=1;i<=tot;++i)M*=p[i];
    	for(int i=1;i<=tot;++i)pp[i]=M/p[i];
    	for(int o=1;o<=tot;++o){
    		ll P=p[o];
    		inv[1]=1;for(int i=2;i<P;++i)inv[i]=(P-(P/i)*inv[P%i]%P)%P;
    		tt[o]=inv[pp[o]%P];
    		fact[0]=1;for(int i=1;i<P;++i)fact[i]=fact[i-1]*i%P;
    		Ans[o]=Lucas(n+m,n,P);
    		for(int i=1;i<=t;++i){
    			f[i]=Lucas(a[i].x+a[i].y,a[i].x,P);
    			for(int j=1;j<i;++j)
    				if(a[j].x<=a[i].x&&a[j].y<=a[i].y)
    					f[i]+=P-f[j]*Lucas(a[i].x+a[i].y-a[j].x-a[j].y,a[i].x-a[j].x,P)%P;
    			f[i]%=P;
    			Ans[o]+=P-Lucas(n+m-a[i].x-a[i].y,n-a[i].x,P)*f[i]%P;
    		}
    		Ans[o]%=P;
    	}
    	ll ans=0;
    	for(int i=1;i<=tot;++i)ans+=Ans[i]*pp[i]%mod*tt[i]%mod;
    	printf("%lld
    ",ans%mod);
    	return 0;
    }
    
  • 相关阅读:
    NetCore实现404和500状态码自定义处理页面
    分享一款好玩的工具
    React三大属性
    谷歌浏览器安装react-developer-tools报错
    初次使用create-react-app
    聊聊webservice
    对java一点感悟
    设计模式之二策略模式(java实现)
    设计模式之一单例模式(java实现)
    java回调函数
  • 原文地址:https://www.cnblogs.com/xzz_233/p/9737194.html
Copyright © 2011-2022 走看看