zoukankan      html  css  js  c++  java
  • BZOJ5093 图的价值

    Solution

    先审对题,图并不要求联通,那么有:

    [ans=nsum_{i=1}^{n-1} i^kinom {n-1} i 2^{frac{(n-1)(n-2)} 2} ]

    把后面的提到前面,得到 (Codeforces932E)

    那么套上式子:

    [sum_{i=1}^n inom n i i^k=sum_{i=1}^k 2^{n-i} inom n i S(k,i) imes i! ]

    求一行用 (NTT) 即可

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define reg register
    namespace yspm{
        inline int read(){
            int res=0,f=1; char k;
            while(!isdigit(k=getchar())) if(k=='-') f=-1;
            while(isdigit(k)) res=res*10+k-'0',k=getchar();
            return res*f;
        }
        const int mod=998244353,N=6e5+10;
        inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
        inline int del(int x,int y){return x-y<0?x-y+mod:x-y;}
        inline int mul(int x,int y){return x*y-x*y/mod*mod;}
        inline int ksm(int x,int y){int res=1; for(;y;y>>=1,x=mul(x,x)) if(y&1) res=mul(res,x); return res;}
        int fac[N],inv[N],n,k,r[N];
        inline void NTT(int *f,int lim,int fl){
            for(reg int i=0;i<lim;++i) r[i]=r[i>>1]>>1|((i&1)?(lim>>1):0);
            for(reg int i=0;i<lim;++i) if(i<r[i]) swap(f[i],f[r[i]]); 
            for(reg int p=2;p<=lim;p<<=1){
                int len=p>>1,tmp=ksm(3,(mod-1)/p); if(fl==-1) tmp=ksm(tmp,mod-2);
                for(reg int k=0;k<lim;k+=p){
                    int buf=1; for(reg int l=k;l<k+len;++l){
                        int tt=mul(buf,f[l+len]); f[l+len]=del(f[l],tt); f[l]=add(f[l],tt); 
                        buf=mul(buf,tmp);           
                    }
                }
            } if(fl==-1) for(reg int i=0;i<lim;++i) f[i]=mul(f[i],ksm(lim,mod-2)); return ;
        }
        int A[N],B[N],S[N];
        inline void Str(int n){
            for(reg int i=0;i<=n;++i) A[i]=mul((i&1)?mod-1:1,inv[i]),B[i]=mul(ksm(i,n),inv[i]);
            int lim=1; while(lim<=(n<<1)) lim<<=1; NTT(A,lim,1); NTT(B,lim,1); 
            for(reg int i=0;i<lim;++i) S[i]=mul(A[i],B[i]); NTT(S,lim,-1);
            return ;
        }
        signed main(){
            n=read(); k=read(); fac[0]=fac[1]=inv[0]=inv[1]=1; for(reg int i=2;i<N;++i) fac[i]=mul(i,fac[i-1]),inv[i]=mod-mul(mod/i,inv[mod%i]);  
            for(reg int i=1;i<N;++i) inv[i]=mul(inv[i],inv[i-1]); Str(k); 
            int ans=0,bas=mul(n,ksm(2,(n-2)*(n-1)/2)),cur=n-1; 
            for(reg int i=1;i<=min(n-1,k);++i,cur=mul(cur,n-i)) ans=add(ans,mul(S[i],mul(cur,ksm(2,n-i-1))));
            printf("%lld
    ",mul(ans,bas));
            return 0;
        }
    }
    signed main(){return yspm::main();}
    

    审对了题就很简单了

  • 相关阅读:
    java第二次作业 数组和String类
    java第一次作业
    选择
    latex math
    sum的写法
    qt 4.8.5 vs 2012编译
    物联网笔记四:物联网网络及协议
    物联网学习笔记三:物联网网关协议比较:MQTT 和 Modbus
    物联网学习笔记二:物联网网关
    物联网学习笔记一:物联网入门的必备 7 大概念和技能
  • 原文地址:https://www.cnblogs.com/yspm/p/14333572.html
Copyright © 2011-2022 走看看