免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
分析
質問ああ、本当に素晴らしいです!!!!
その確率で割った合法的なプログラムの計画で
、一般的な計画は明らかに
それは素晴らしいプログラムは合法的である
とさえリングに、場所を追加することを検討
してい(選挙は誰もが座って場所を見つけることができるようにどれだけ)合法で、その後、プログラムのすべてを
種は、円形配置ので、によって分割され
次に、チェーンにリングを壊す検討、各空位置は、我々が持って切断することができます
メソッド
(この位置が空の場合、確かに誰がそれを越えていないので、それ以外の場合はこの位置に座って優先順位を与える必要があります)
だから、最終的な答えであります
その後〜行く正確に転送します
コード
#include<bits/stdc++.h>
#define in read()
#define re register
using namespace std;
inline int read(){
char ch;int f=1,res=0;
while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
while(ch>='0'&&ch<='9'){
res=(res<<1)+(res<<3)+(ch^48);
ch=getchar();
}
return f==1?res:-res;
}
int T,n,k;
int a[205],b[205];
struct BigNumber{
int len,s[505];//s长度
BigNumber(){
memset(s,0,sizeof(s));//!!!!!
len=0;
}
inline void operator = (int x){
BigNumber res;
res.len=0;
while(x){
res.s[++res.len]=x%10;
x/=10;
}
*this=res;
}
inline BigNumber operator *(const BigNumber y){
BigNumber res;
res.len=y.len+len;
for(re int i=1;i<=y.len;++i)
for(re int j=1;j<=len;++j){
res.s[i+j-1]+=y.s[i]*s[j];
res.s[i+j]+=res.s[i+j-1]/10;
res.s[i+j-1]%=10;
}
int &l=res.len;
while(res.s[l]) res.s[l+1]+=res.s[l]/10,res.s[l]%=10,l++;
while(!res.s[l]) l--;
return res;
}
void out(){
for(re int i=len;i>=1;--i) printf("%d",s[i]);
printf(" ");
}
}a1,b1;
void work(){
int t=k;
for(re int i=2;i<=200;++i){
while(t%i==0){
t/=i;
a[i]+=n;
}
}
t=k+1;
for(re int i=2;i<=200;++i){
while(t%i==0){
t/=i;
b[i]+=n-1;
}
}
t=k+1-n;
for(re int i=2;i<=200;++i){
while(t%i==0){
t/=i;
b[i]++;
}
}
for(re int i=2;i<=200;++i){
int hh=min(a[i],b[i]);
a[i]-=hh;b[i]-=hh;
}
a1=1;b1=1;
for(re int i=2;i<=200;++i){
BigNumber tmp;
tmp=i;
while(a[i]){
a1=a1*tmp;
a[i]--;
}
}
for(re int i=2;i<=200;++i){
BigNumber tmp;
tmp=i;
while(b[i]){
b1=b1*tmp;
b[i]--;
}
}
}
int main(){
scanf("%d",&T);
while(T--){
n=in;k=in;
if(k<n){
printf("0 1\n");
continue;
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
work();
b1.out();
a1.out();
printf("\n");
}
return 0;
}