列表

详情


NC18203. 子序列

描述

给出一个长度为n的序列,你需要计算出所有长度为k的子序列中,除最大最小数之外所有数的乘积相乘的结果

输入描述

第一行一个整数T,表示数据组数。
对于每组数据,第一行两个整数N,k,含义如题所示

接下来一行N个整数,表示给出的序列

保证序列内的数互不相同

输出描述

对于每组数据,输出一个整数表示答案,对取模
每组数据之间以换行分割

示例1

输入:

3
4 3 
5 3 1 4
5 4
3 7 5 2 1
10 3 
100 1020 2050 102 12 235 4 57 32135 54354 

输出:

144
81000
521918013

说明:

第一组数据解释
所有长度为3的子序列为
最终答案为

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 495ms, 内存消耗: 23272K, 提交时间: 2018-09-06 21:25:12

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2005;
const int mod=1e9+7;
typedef long long ll;
int n,q,k;
ll a[N];
ll c[N][N];
ll qm(ll x,ll y) {
	ll ret=1;
	while(y) {
		if(y%2==1) ret=(ret*x)%mod;
		x=(x*x)%mod;
		y/=2;
	}
	if(ret<0) ret=(ret+mod)%mod;
	return ret%mod;
}
signed main() {
	for(int i=0; i<=2001; i++) {
		c[i][0]=1;
		for(int j=1; j<=i; j++) {
			c[i][j]=(c[i-1][j-1]+c[i-1][j])%(mod-1);
		}
	}
	scanf("%lld",&q);
	while(q--) {
		scanf("%lld%lld",&n,&k);
		for(int i=1; i<=n; i++)scanf("%lld",&a[i]);
		sort(a+1,a+n+1);
		ll ans=1;
		for(int i=1; i<=n; i++) {
			ll ci=(c[n-1][k-1]-c[i-1][k-1]-c[n-i][k-1]+2*(mod-1))%(mod-1);

			ans=(ans*qm(a[i],ci))%mod;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

C++(g++ 7.5.0) 解法, 执行用时: 404ms, 内存消耗: 13760K, 提交时间: 2023-07-09 15:20:03

#include<bits/stdc++.h>
#define P 1000000007
#define ll long long
using namespace std;
const int p=P-1;
ll C[1001][1001],a[1001];
int n,m,k;
inline ll mul(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1) ans=(ans*a)%P;
		a=(a*a)%P;
		b>>=1;
	}
	return ans;
}
int main()
{
	C[0][0]=1;
	for(int i=1;i<=1000;++i)
	{
		C[i][0]=1;
		for(int j=1;j<=i;++j) C[i][j]=C[i-1][j-1]+C[i-1][j],C[i][j]%=p;
	}
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
		sort(a+1,a+1+n);
		ll ans=1;
		for(int i=2;i<n;++i)
			ans=(ans*mul(a[i],((C[n-1][m-1]-C[i-1][m-1]-C[n-i][m-1])%p+p)%p))%P;
		printf("%lld\n",ans);
	}
}

上一题