您的位置:首页 > 其它

2227: [Zjoi2011]看电影(movie)

2016-10-22 21:10 411 查看
经典思路:线转化为圈,利用对称性

假设有k+1个椅子围成一圈,每张票上写着1~k+1(而不是1~k),因为概率均等,我们统计有多少种方案导致椅子k+1上坐着人

一共有(k+1)n种可能的情况。为了方便叙述,我们假定每种情况模拟一遍,每次在没人坐的椅子上放一枚硬币(每次恰好有k+1-n把椅子没人坐),则所有情况都模拟完之后每把椅子上都有(k+1-n)(k+1)n-1枚硬币,也就是说,有(k+1-n)(k+1)n-1种情况下,椅子k+1上没人坐。

改回每张票写1~k之后,这个结论不变。——————-from liurujia

#include<bits/stdc++.h>
#define rep(i,k,n) for(int i=k;i<=n;i++)
#define rep2(i,k,n) for(int i=k;i>=n;i--)
using namespace std;
const int N=1000005;
int gcd(int a,int b){return !b ? a : gcd(b,a%b);}
struct gao{
int num
,len;
void init(){len=1;memset(num,0,sizeof(num));}
void put(){
printf("%d",num[len]);
rep2(i,len-1,1)printf("%04d",num[i]);
}
void operator*=(int x){
rep(i,1,len)num[i]*=x;
for(int i=1;i<=len || num[i];i++)num[i+1]+=num[i]/10000,num[i]%=10000,len=max(len,i);
}
}A,B;
int T,k,n,a
,b
;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&k);
if(n>k){printf("0 1\n");continue;}
rep(i,1,n)a[i]=k+1,b[i]=k;
a
=(k+1-n);
rep(i,1,n){int d=gcd(a
,b[i]);a
/=d,b[i]/=d;}
A.init(),B.init();
A.num[1]=1,B.num[1]=1;
rep(i,1,n){
A*=a[i];
B*=b[i];
}
A.put();printf(" ");B.put();puts("");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学 对称性