打牌的贝贝
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 

BeiBeiBeiBei和NingNingNingNing在玩一个卡牌游戏,共有2n2n张卡牌,每张牌上都有一个整数,介于11和2n2n之间,所有牌上的数字都是不同的。发牌阶段二人都拿到了nn张牌。每个回合,游戏的过程如下:
  1. 若此时BeiBeiBeiBei没有牌了,则BeiBeiBeiBei判负。
  2. BeiBeiBeiBei打出一张牌。
  3. 然后NingNingNingNing需要打出一张牌,使得其上的数字比BeiBeiBeiBei最新打出的一张牌上的数字大,如果此时NingNingNingNing无法打出这样的牌,则NingNingNingNing判负。
容易证明,该游戏总有一方会被判负。BeiBeiBeiBei和NingNingNingNing都足够聪明。考虑所有可能的分牌情况,使他们每个人正好分到nn张牌。当BeiBeiBeiBei和NingNingNingNing都足够聪明时,求解出其中BeiBeiBeiBei、NingNingNingNing各自获胜的情况数量。

输入描述:

第一行,一个正整数T(1\le T\le 10^6)T(1T106),表示测试数据组数。

每组测试数据一行,包含一个整数n(1\le n\le 10^6)n(1n106)。

输出描述:

对于每组数据,输出一行,包含两个整数,分别表示BeiBeiBeiBei、NingNingNingNing获胜的情况数量,答案对10^9+7109+7取模。
示例1

输入

复制
6
1
1
4
5
1
4

输出

复制
1 1
1 1
56 14
210 42
1 1
56 14
#include <bits/stdc++.h>
#define fi first
#define se second 
using namespace std;
const int N=2e6+10; 
const int M=2e5+10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef pair<int,int>PII;
typedef pair<LL,LL>PLL;
LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b) {return a/gcd(a,b)*b;}
LL lowbit(LL a){return a&-a;}
//8个方向的和4个方向的是不同的计算方法

int t; 
int n;
LL st[N],str[N];//分别为阶乘和逆元

LL qmi(LL a,LL p)
{
	LL res=1;
	while(p)
	{
		if(p&1)res*=a,res%=mod;
		a*=a,a%=mod;
		p>>=1;
	}
    return res;
}
int main()
{
   scanf("%d",&t);
    
   st[0]=1,str[0]=1;
   for(int i=1;i<=N;i++)
   {
   	 st[i]=(LL)st[i-1]*i%mod;
   	 str[i]=(LL)str[i-1]*qmi((LL)i,(LL)mod-2)%mod;
   }
 
   while(t--)
   {
   	scanf("%d",&n);
   	LL res=st[2*n]*str[n]%mod*str[n]%mod;
   	printf("%lld %lld\n",res*qmi(n+1,mod-2)%mod*n%mod,res*qmi(n+1,mod-2)%mod);
   }
   
    return 0;
}

  这道题实际上属于一种打表题:

打表的方法:

 

 

关键问题:

printf("%lld %lld\n",res*qmi(n+1,mod-2)%mod*n%mod,res*qmi(n+1,mod-2)%mod);
这里只能够是对res进行取模运算,不可以进行除法运算(通过打表发现的规律)
printf("%lld %lld\n",res/(n+1)*n,res/(n+1));这种做法属于错误的
posted on 2022-11-04 22:10  浅唱\,,笑竹神易  阅读(33)  评论(0)    收藏  举报