七夕节到了,摸了几天鱼之后给自己找了一道数学题做做。
P4931 情侣?给我烧了!(加强版)
大体意思……嗯,是一道有趣的数学题。
那么就开始我们的数学吧!
首先按题意,找k对情侣就坐\(\binom{n}{k} \)
Fine 同理 n排中找k排也是\(\binom{n}{k}\),同时有 k!
同时k对情侣各人可交换\(2^{k}\)
即有\(2^{k}*\binom{n}{k}*\binom{n}{k}*k!\)
嗯嗯,做到这里发现其实很简单呢(x
问题是剩下的n-k对怎么排????既要考虑各对“完整”与否,也要考虑相对位置?有点错排的味道
设出 G(x)为 x对情侣不能坐在一起的方案数 。
假设剩下的情况中,让第一对不是情侣的坐在一起的话就有 2x*(2x-2) 的情况(其中x=n-k) \(*_{1}\)
T1
剩下的x-1对的人中,有刚刚不能做到一起的各自的伴侣(nice!
- 如果那两个人自己又组合了(好狗血!考虑两人交换位置,那就是 2x*(2x-2)*(余排数)*2 = 2x*(2x-2)*(n-1)*2 ,再乘上G(x-2);
- 如果那两个人没有坐在一起 , 那么就是这两个人可以继续去和别人的伴侣坐!所以 2x*(2x-2) 直接乘上G(x-1)即可;
综上,容易得到递推式G(x) = 2x*(2x-2)*[ (n-1)*2*G(x-2) + G(x-1) ];
ans =
\({\small 2^{k}\binom{n}{k}^{2}k! *2x*(2x-2)[ (n-1)*2G(x-2) + G(x-1) ]}\)
需要预处理的是 阶乘 阶乘的逆元 2幂 G(x) from 0 to maxn
时间复杂度为O( logMod + n )
T2
有一种无脑推的方式,就是利用生成函数
对于\(*_{1}\)式 , 乘上 G(n-k)得\(2^{k}*\binom{n}{k}*\binom{n}{k}*k!*G(n-k)\)
求和即有 :
\[\sum_{k=0}^{n}[\binom{n}{k}^{2}\cdot k!\cdot 2^{k}\cdot G(n-k)]= (2n)!\]
\[{\scriptsize\sum_{k=0}^{n}\left \{ [\frac{n(n-1)...(n-k+1)}{k!}]^{2}\cdot k!\cdot 2^{k}\cdot G(n-k)\right \}= (2n)!}\]
\[ (n!)^{2}\sum_{k=0}^{n}\left \{ \frac{\cdot 2^{k}\cdot G(n-k)}{k![(n-k)!]^{2}}\right \}= (2n)!\]
\[ \sum_{k=0}^{n}\left \{ \frac{\cdot 2^{k}\cdot G(n-k)}{k![(n-k)!]^{2}}\right \}= \frac{(2n)!}{(n!)^{2}}\]
接下来就是EGF的标准步骤了,引入\( x^{n}\),并对两边同求和
\[{\scriptsize\sum_{n=0}^{\infty}\left [ \frac{2^{n}\cdot x^{n}}{n!}\right ]\cdot \sum_{n=0}^{\infty }\left [ \frac{G(n)\cdot x^{n}}{(n!)^{2}} \right ]=\sum_{n=0}^{\infty }[\frac{(2n)!}{(n!)^{2}}*x^{n}]}\]
右式考虑级展还原:
\[ e^{2x}= \sum_{n=0}^{\infty }[\frac{(2n)!}{(n!)^{2}}*x^{n}] \]
\[ \sum_{n=0}^{\infty }\left [ \frac{G(n)\cdot x^{n}}{(n!)^{2}} \right ]=\frac{1}{e^{2x}\cdot \sqrt{1-4x}}\]
记作
\( G(n)_{x}=\frac{1}{e^{2x}\cdot \sqrt{1-4x}}\)
求导得
\(\left \{ \sum_{n=0}^{\infty }\left [ \frac{G(n)\cdot x^{n}}{(n!)^{2}} \right ] \right \}^{'}=\frac{8x}{e^{2x}\cdot \sqrt{1-4x}\cdot (1-4x)} \)
\( \left \{ \sum_{n=0}^{\infty }\left [ \frac{G(n)\cdot x^{n}}{(n!)^{2}} \right ] \right \}^{'}=\frac{8x}{1-4x}\cdot \sum_{n=0}^{\infty }\frac{G(n)\cdot x^{n}}{(n!)^{2}}\)
这是一个比较简单的微分方程
解之后还原系数并提取就行了
最终也可以得到\({\scriptsize G(x) = 2x*(2x-2)*[ (n-1)*2*G(x-2) + G(x-1) } ]\)
Code
/*
.
';;;;;.
'!;;;;;;!;`
'!;|&#@|;;;;!:
`;;!&####@|;;;;!:
.;;;!&@$$%|!;;;;;;!'.`:::::'.
'!;;;;;;;;!$@###&|;;|%!;!$|;;;;|&&;.
:!;;;;!$@&%|;;;;;;;;;|!::!!:::;!$%;!$%` '!%&#########@$!:.
;!;;!!;;;;;|$$&@##$;;;::'''''::;;;;|&|%@$|;;;;;;;;;;;;;;;;!$;
;|;;;;;;;;;;;;;;;;;;!%@#####&!:::;!;;;;;;;;;;!&####@%!;;;;$%`
`!!;;;;;;;;;;!|%%|!!;::;;|@##%|$|;;;;;;;;;;;;!|%$#####%;;;%&;
:@###&!:;;!!||%%%%%|!;;;;;||;;;;||!$&&@@%;;;;;;;|$$##$;;;%@|
;|::;;;;;;;;;;;;|&&$|;;!$@&$!;;;;!;;;;;;;;;;;;;;;;!%|;;;%@%.
`!!;;;;;;;!!!!;;;;;$@@@&&&&&@$!;!%|;;;;!||!;;;;;!|%%%!;;%@|.
%&&$!;;;;;!;;;;;;;;;;;|$&&&&&&&&&@@%!%%;!||!;;;;;;;;;;;;;$##!
!%;;;;;;!%!:;;;;;;;;;;!$&&&&&&&&&&@##&%|||;;;!!||!;;;;;;;$&:
':|@###%;:;;;;;;;;;;;;!%$&&&&&&@@$!;;;;;;;!!!;;;;;%&!;;|&%.
!@|;;;;;;;;;;;;;;;;;;|%|$&&$%&&|;;;;;;;;;;;;!;;;;;!&@@&'
.:%#&!;;;;;;;;;;;;;;!%|$$%%&@%;;;;;;;;;;;;;;;;;;;!&@:
.%$;;;;;;;;;;;;;;;;;;|$$$$@&|;;;;;;;;;;;;;;;;;;;;%@%.
!&!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|@#;
`%$!;;;;;;;;;;;$@|;;;;;;;;;;;;;;;;;;;;;;;;!%$@#@|.
.|@%!;;;;;;;;;!$&%||;;;;;;;;;;;;;;;;;!%$$$$$@#|.
;&$!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%#####|.
|##$|!;;;;;;::'':;;;;;;;;;;;;;!%$$$@#@;
;@&|;;;;;;;::'''''':;;;;;;;|$&@###@|`
.%##@|;;;;:::''''''''''::;!%&##$'
`$##@$$@@&|!!;;;:'''''::::;;;;;|&#%.
;&@##&$%!;;;;;;::''''''''::;!|%$@#@&@@:
.%@&$$|;;;;;;;;;;:'''':''''::;;;%@#@@#%.
:@##@###@$$$$$|;;:'''':;;!!;;;;;;!$#@@#$;`
`%@$$|;;;;;;;;:'''''''::;;;;|%$$|!!&###&'
|##&%!;;;;;::''''''''''''::;;;;;;;!$@&:`!'
:;!@$|;;;;;;;::''''''''''':;;;;;;;;!%&@$: !@#$'
|##@@&%;;;;;::''''''''':;;;;;;;!%&@#@$%: '%%!%&;
|&%!;;;;;;;%$!:''''''':|%!;;;;;;;;|&@%||` '%$|!%&;
|@%!;;!!;;;||;:'''''':;%$!;;;;!%%%&#&%$&: .|%;:!&%`
!@&%;;;;;;;||;;;:''::;;%$!;;;;;;;|&@%;!$; `%&%!!$&:
'$$|;!!!!;;||;;;;;;;;;;%%;;;;;;;|@@|!$##; !$!;:!$&:
|#&|;;;;;;!||;;;;;;;;!%|;;;;!$##$;;;;|%' `%$|%%;|&$'
|&%!;;;;;;|%;;;;;;;;$$;;;;;;|&&|!|%&&; .:%&$!;;;:!$@!
`%#&%!!;;;;||;;;;;!$&|;;;!%%%@&!;;;!!;;;|%!;;%@$!%@!
!&!;;;;;;;;;||;;%&!;;;;;;;;;%@&!;;!&$;;;|&%;;;%@%`
'%|;;;;;;;;!!|$|%&%;;;;;;;;;;|&#&|!!||!!|%$@@|'
.!%%&%'`|$; :|$#%|@#&;%#%.
*/
#pragma comment(linker,"/STACK:1024000000,1024000000")
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define lodou long double
#define lll __int128
#define INmF 0x3f3f3f3f
#define lbt(x) (x&(-x))
#define mes(a,b) memset(a,b,sizeof(a))
#define qwq(a,b) for(int register i=a ;i<=b;++i)
#define qeq(a,b) for(int j=a ;j<=b;++j)
#define IOS ios::sync_with_stdio(false)
#define UPCASE( c ) ( ((c) >= 'c' && (c) <= 'z') ? ((c) - 0x20) : (c) )
#define pb push_back
#define mkp make_pair
using namespace std;
using namespace __gnu_pbds;
using pii=pair<int,int>;
using Balanced_Tree=tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>;
Balanced_Tree seq;
const double Eps = 1e-8 ;
const double pi = acos(-1) ;
const long long mod = 1e9+7 ;
typedef long long int ll;
inline ll pow_mod (ll a,ll b) {ll res=1;a%=mod; if(b<0) return -1; for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
inline ll fas_mul (ll a,ll b) { return ( (a*b-(ll)(((long double)a*b+0.5)/mod)*mod)%mod+mod)%mod ; }
namespace IO{
inline char get_char(){
static const int Rlen=1<<20|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
inline int getint(){
register char c;
while(!isdigit(c=get_char()));register int num=c^48;
while( isdigit(c=get_char()))num=(num+(num<<2)<<1)+(c^48);
return num;
}
}using namespace IO;
namespace io {
#define in(a) a=read()
#define out(a) write(a)
#define outn(a) out(a),putchar('\n')
#define I_int __int128
inline I_int read() {
I_int x = 0 , f = 1 ; char c = getchar() ;
while( c < '0' || c > '9' ) { if( c == '-' ) f = -1 ; c = getchar() ; }
while( c >= '0' && c <= '9' ) { x = x * 10 + c - '0' ; c = getchar() ; }
return x * f ;
}
char F[ 200 ] ;
inline void write( I_int x ) {
if( x == 0 ) { putchar( '0' ) ; return ; }
I_int tmp = x > 0 ? x : -x ;
if( x < 0 ) putchar( '-' ) ;
int cnt = 0 ;
while( tmp > 0 ) {
F[ cnt ++ ] = tmp % 10 + '0' ;
tmp /= 10 ;
}
while( cnt > 0 ) putchar ( F[ -- cnt ] ) ;
}
#undef I_int
}using namespace io ;
const long long int N = 5e6+50 ;
const long long int Mod=998244353 ;
int fac[N] , inv[N] , ifac[N] , pwo[N] , G[N] ;
inline int mul( int a , int b ){
return (ll)a*b%Mod ;
}
inline int add( int a , int b ){
return a+b>=Mod ? a+b-Mod : a+b ;
}
template<class ...Args>
inline int mul( const int a , const int b,const Args &...args ){
return mul(mul(a,b),args...);
}
inline int pw2( int x ){
return (ll)x*x%Mod ;
}
inline int ccc( int a , int b ){
return mul( fac[a] , mul( ifac[b] , ifac[a-b] )) ;
}
signed main()
{
fac[0] = fac[1] = ifac[0] = ifac[1] = inv[1] = pwo[0] = 1ll ;//ini
pwo[1] = 2ll , G[0] = 1ll ;//
qwq( 2 , N ){
fac[i] = mul ( fac[i-1] , i ) ;
inv[i] = mul ( inv[Mod%i] , Mod-Mod/i ) ;
ifac[i] = mul ( ifac[i-1] , inv[i] ) ;//一定在inv之后
pwo[i] = add ( pwo[i-1] , pwo[i-1] ) ;
G[i] = mul ( 4ll , i , i-1 , add( G[i-1] , mul( 2ll , i-1 , G[i-2]) ) ) ;
}
int t=read();
while( t-- )
{
int n=read() , k=read() ;
outn( mul( pw2( ccc( n,k ) ) , fac[k] , pwo[k] , G[n-k] ) ) ;
}
}
学艺不精,告辞