ACM_洛谷p4931烧情侣

七夕节到了,摸了几天鱼之后给自己找了一道数学题做做。

(数学公式炸了可以刷新一下QWQ)

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!

  1. 如果那两个人自己又组合了(好狗血!考虑两人交换位置,那就是 2x*(2x-2)*(余排数)*2 = 2x*(2x-2)*(n-1)*2 ,再乘上G(x-2);
  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] ) ) ;
	}
	
}

学艺不精,告辞

喜欢这篇文章吗,不妨分享给朋友们吧!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值