2018.11.01-dtoj-4019-白玉楼前(youmu)

题目描述:

妖梦现在要玩幽幽子的游戏,她才能拿回自己的半灵。
游戏规则是这样的:
幽幽子有n 个点,现在她让妖梦对每个点随机一条出边(随机到每个点的概率都相等),
然后得到一张图。(注意:可以自环)
如果这张图任意一个点沿着边走两步(显然这样的走法唯一)都能到达自身,则幽幽子
可以通关。
现在幽幽子想问妖梦,她通关的概率是多少?
两个图不同,当且仅当存在一条边出现在图A 中且不出现在图B 中。图中的点有编号,
边无编号。
答案mod 998244353。

输入:

下面T 行,每行中只有一个数,表示n。

输出:

输出T 行,每行一个数表示答案。

数据范围:

T≤5*105,n<=5*105

算法标签:推式子

思路:

式子可以从上一层推过来,f[i]=f[i-1]+(n-1)f[i-2];表示你可以把新加的自己连自己,或者和某一个相互连接。

忏悔录:为什么想错方向了啊...神犇说一眼就推出式子...哭了唉

以下代码:

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define LL long long
#define re register
#define _(d) while(d(isdigit(ch=getchar())))
const int N=5e5,p=998244353,M=5e5+5;;
LL ny[M],jc[M],sum,res[M],kk[M],kt[M],f[N];int n;
il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;}
il LL ksm(LL a,int y){LL b=1;while(y){if(y&1)b=b*a%p;a=a*a%p;y>>=1;}return b;}
il LL mu(LL a){if(a>=p)return a-p;return a;}
int main()
{
    //freopen("youmu.in","r",stdin);
    //freopen("youmu.out","w",stdout);
    f[0]=1;f[1]=1;
    for(int i=2;i<=N;i++)f[i]=mu(f[i-1]+f[i-2]*(LL)(i-1)%p);
    int T=read();while(T--){
        n=read();
        printf("%lld\n",f[n]*ksm(ksm(n,n),p-2)%p);
    }
  return 0;
}
View Code

 

posted @ 2018-11-01 13:25  Jessiejzy  阅读(192)  评论(0编辑  收藏  举报