zoukankan      html  css  js  c++  java
  • Tom and matrix

    题目

    (sum_{i=x_1}^{x_2}sum_{j=y_1}^{y_2} ext C[i][j]mod p)

    要求在 (mathcal O(y)) 的复杂度求解。

    解法

    组合数有一个式子:(C[i][j]=C[i-1][j-1]+C[i-1][j])

    我们可以这样理解一下这个式子:如果我们先枚举 (j) 再枚举 (i),那么其实 ( ext C[i][j]) 存储了 ( ext C[i-1][j-1]) 的前缀和!

    而我们这道题迫切需要的就是前缀和的优化。

    可以得出:

    [sum_{i=x_1}^{x_2}C[i][j]=C[x_2+1][j+1]-C[x_1][j+1](y_1le jle y_2) ]

    解释一下:(C[x_1][j+1]) 就是 (sum_{i=1}^{x_1-1}C[i][j])。前者同理。

    因为模数在线,所以用卢卡斯定理求解。

    代码

    #include <cstdio>
    typedef long long ll;
    
    ll p, fac[100005];
    
    int read() {
    	int x = 0, f = 1; char s;
    	while((s = getchar()) > '9' || s < '0') if(s == '-') f = -1;
    	while(s <= '9' && s >= '0') {
    		x = (x << 1) + (x << 3) + (s ^ 48);
    		s = getchar();
    	}
    	return x * f;
    }
    
    ll qkpow(ll x, ll y) {
    	ll r = 1;
    	while(y) {
    		if(y & 1) r = r * x % p;
    		x = x * x % p; y >>= 1;
    	}
    	return r;
    }
    
    ll C(const int n, const int m) {
    	if(n < m) return 0;
    	return fac[n] * qkpow(fac[m] * fac[n - m] % p, p - 2) % p;
    }
    
    ll Lucas(const int n, const int m) {
    	if(n < m) return 0;
    	if(! m) return 1;
    	return Lucas(n / p, m / p) * C(n % p, m % p) % p;
    }
    
    void init() {
    	fac[0] = 1;
    	for(int i = 1; i <= 100000; ++ i) fac[i] = fac[i - 1] * i % p;
    }
    
    int main() {
    	int x1, x2, y1, y2; ll ans;
    	while(~ scanf("%d %d %d %d %lld", &x1, &y1, &x2, &y2, &p)) {
    		ans = 0; init();
    		for(int i = y1; i <= y2; ++ i) ans = (ans + Lucas(x2 + 1, i + 1) - Lucas(x1, i + 1) + p) % p;
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    简单工厂模式
    原型模式
    特性Attribute
    MVC_Route层层深入
    异步Async
    sql-connectionStrings
    观察者模式(利用委托)
    SqlServer_存储过程
    c语言----程序记录
    c语言基础笔记
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/12752596.html
Copyright © 2011-2022 走看看