假设两个人及以上便可创建一个QQ群,那么n个人的宿舍最多可能有几个不一样的QQ群呢?
输入
第一行有一个整数T,代表有T组数据。
下面T行每行是一个整数n,代表这个宿舍有n个人。
1<=T<=105
1<=n<=109
输出
对于每一个结果可能很大,所以你只需要输出对1000000007取模的结果
解题思路:
组合数Cn0+Cn1+Cn2+...+Cnn=2^n,证明可以用二进制数,0表示不取1表示取,其组合数共2^n种
程序代码:
#include<stdio.h>
#include<string.h>
const long long N=1000000007;
long long N1;
long long F(long long m,long long n);
int main()
{
long long n,a,T,sum,p;
scanf("%lld",&T);
while(T--)
{
sum=1;
a=2;
scanf("%lld",&n);
p=n;
N1=n+1;
while(p)
{
if(p%2==1)
sum=F(sum,a);
a=F(a,a);
p/=2;
}
printf("%lld\n",(sum-n-1)%N);
}
return 0;
}
long long F(long long m,long long n)
{
long long a[110],b[110],c[110],d[110];
long long sum,t,i=0,j=0,k,p,q;
while(m)
{
a[i++]=m%10;
m/=10;
}
while(n)
{
b[j++]=n%10;
n/=10;
}
memset(c,0,sizeof(c));
for(p=0;p<i;p++)
for(q=0;q<j;q++)
c[p+q]+=a[p]*b[q];
t=0;
for(k=0;k<i+j-1;k++)
{
d[k]=(c[k]+t)%10;
t=(c[k]+t)/10;
}
while(t)
{
d[k++]=t%10;
t/=10;
}
sum=0;
for(i=k-1;i>=0;i--)
{
sum=10*sum+d[i];
if(sum%N>N1)
sum=sum%N;
}
return sum;
}