Subsequence (combinatorial mathematics)

Link: https://www.nowcoder.com/acm/contest/181/F
Source: Niuke

Title description

Given a sequence of length n, you need to calculate the result of multiplying the product of all numbers except the largest and smallest numbers in all subsequences of length k

answer

The contribution
of each number is just fine. For each number, the contribution of this number === The number of all subsequences containing this number−-- containing this number and this number is the minimum number of sub-sequence- - Contains this number and this number is the maximum number of the subsequence.
It is not difficult to find, you need to sort first

Knowledge integration

Euler Powers

a b ≡ a b % φ ( p ) ( m o d    p ) a ^ b \equiv a ^ {b \% \varphi(p)} (mod~~ p) abab % φ ( p ) (modp)  
Euler's reduced power is the power pairφ (p) \varphi(p)φ ( p ) is modulo instead ofppp
b b All items in b must be preprocessed toφ (p) \varphi(p)φ ( p ) modulo

Yanghui triangle

Simple preprocessing

#include<iostream>
#include<algorithm>
using namespace std;

#define mod 1000000007
typedef long long ll;
const int N = 1e3 + 10;

ll u[N];

ll c[N][N];

ll qpow(ll a, ll b, ll p) {
    
    
	ll res = 1;
	while (b) {
    
    
		if (b & 1) {
    
    
			res = res * a % mod;
		}
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}
void init_com(const int n = 1e3) {
    
    
	for (int i = 0; i <= n; i++) {
    
    
		for (int j = 0; j <= i; j++) {
    
    
			if (i == j || j == 0) c[i][j] = 1;
			else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % (mod - 1);
		}
	}
}
int main() {
    
    

	//杨辉三角初始化组合数 
	init_com();
	int T; cin >> T;

	while (T--) {
    
    
		int n, k;
		cin >> n >> k;

		for (int i = 1; i <= n; i++) {
    
    
			cin >> u[i];
		}

		sort(u + 1, u + n + 1);

		ll ans = 1;
		for (int i = 1; i <= n; i++) {
    
    
			//容斥  
			//这个数的贡献 = 含这个数的所有情况 - 以u[i]最大 - u[i]最小
			ll t = c[n - 1][k - 1] - c[i - 1][k - 1] - c[n - i][k - 1];
			//欧拉定理 a^b = a^(b % (p - 1)) 
			//所以幂次需要对(mod - 1)取模
			//由于幂次有组合数,所以预处理组合数时,对(mod - 1)取模就行
			t = (t % (mod - 1) + (mod - 1)) % (mod - 1);
			//答案是对mod取模的
			ans = ans * qpow(u[i], t, mod) % mod;
		}

		cout << ans << endl;
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_45739057/article/details/109964528