zoukankan      html  css  js  c++  java
  • 白玉楼前

    白玉楼前
    【题目背景】
    “一觉醒来怎么半灵又不见了?一定是幽幽子吃了。”
    “幽幽子你给我吐出来!”
    “我这边有个游戏玩不过去,你帮我玩过去我就吐出来。”
    【题目描述】
    妖梦现在要玩幽幽子的游戏,她才能拿回自己的半灵。
    游戏规则是这样的:
    幽幽子有n nn 个点,现在她让妖梦对每个点随机一条出边(随机到每个点的概率都相等),
    然后得到一张图。(注意:可以自环)
    如果这张图任意一个点沿着边走两步(显然这样的走法唯一)都能到达自身,则幽幽子可以通关。
    现在幽幽子想问妖梦,她通关的概率是多少?
    两个图不同,当且仅当存在一条边出现在图A 中且不出现在图B 中。图中的点有编号,边无编号。
    答案mod 998244353
     

    【数据范围】
    T≤5×105,n≤5×105 T leq 5 imes 10^5,nleq 5 imes 10^5T≤5×10 
     


    solution

    本题求1~n的排列的对偶排列个数,即满足p[p[i]]=i的p[i]个数.

    令f[i]表示前i个数的答案

    f[i]=f[i-1]+(i-1)*f[i-2];

    也就是它可以和自己对偶p[i]=i;

    或者和任意一个人(i-1) 乘上 i-2个人的答案

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define maxn 500005
    #define ll long long
    #define mod 998244353
    using namespace std;
    int n;
    ll f[maxn],ny[maxn];
    ll work(ll a,int num){
        ll p=a,x=1;
        while(num){
            if(num&1)x=x*p;
            p=p*p;p%=mod;x%=mod;num>>=1;
        }
        return x;
    }
    int main()
    {
        freopen("youmu.in","r",stdin);
        freopen("youmu.out","w",stdout);
        n=500000;
        f[0]=1;f[1]=1;
        for(int i=2;i<=n;i++){
            f[i]=f[i-1]+(ll)(i-1)*f[i-2]%mod;f[i]%=mod;
        }
        for(int i=0;i<=n;i++){
            ny[i]=work(work(i,i),mod-2);
        }
        int T;
        cin>>T;
        for(int i=1;i<=T;i++){
            scanf("%d",&n);
            ll ans=ny[n]*f[n];ans=(ans%mod+mod)%mod;
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    windows10输入法评价
    找水王
    团队项目第九天
    团队项目第八天
    团队项目第七天
    团队项目第六天
    团队项目第四天
    团队项目第五天
    团队项目第三天
    团队项目第二天
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358788.html
Copyright © 2011-2022 走看看