LuoguP6694 强迫症 找规律+NTT

本文介绍了一种计算特定权值和的竞赛算法,利用NTT(Number Theoretic Transform)快速解决复杂问题,通过枚举子图方案数,实现了高效计算。详细解析了代码实现过程,包括多项式乘法、逆元计算等关键步骤。

比赛的时候切的,可惜没抢到首 A.

权值和等于 $\sum_{i=1}^{n} \sum_{j=i+1}^{n} a_{i} \times a_{j} \times f(j-i+1) \times f(n-j+i+2)$,最后再除以 4.  

然后这里的 $f(n)$ 就代表 $n$ 个点构成的圆环的不相交生成子图的方案数.

可以将前 $5$ 项打表打出来,上 $OEIS$ 找到通项公式,然后就可以拿到 $40$pts 的好成绩.         

观察上面的式子,我们发现可以枚举 $f(j-i+1)$ 的长度,然后就要求有贡献的点对距离必须为 $(j-i+1)$,这个用 NTT 来求即可. 

code: 

#include <cstdio>  
#include <cstring>
#include <algorithm>
#define N 100007
#define ll long long 
#define mod 998244353
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
int a[N],pw[N],n,val[N],f[N],A[N<<2],B[N<<2];   
int qpow(int x,int y) { 
    int tmp=1; 
    for(;y;y>>=1,x=(ll)x*x%mod) {   
        if(y&1) {   
            tmp=(ll)tmp*x%mod;  
        }
    }
    return tmp;  
}  
int get_inv(int x) { 
    return qpow(x,mod-2);  
}
void NTT(int *a,int len,int op) { 
    for(int i=0,k=0;i<len;++i) {   
        if(i>k) { 
            swap(a[i],a[k]);
        }  
        for(int j=len>>1;(k^=j)<j;j>>=1);  
    }     
    for(int l=1;l<len;l<<=1) { 
        int wn=qpow(3,(mod-1)/(l<<1));  
        if(op==-1) { 
            wn=get_inv(wn); 
        }  
        for(int i=0;i<len;i+=l<<1) { 
            int w=1;  
            for(int j=0;j<l;++j) { 
                int x=a[i+j],y=(ll)w*a[i+j+l]%mod;  
                a[i+j]=(ll)(x+y)%mod;  
                a[i+j+l]=(ll)(x-y+mod)%mod;  
                w=(ll)w*wn%mod;  
            }
        }
    }
    if(op==-1) { 
        int iv=get_inv(len);  
        for(int i=0;i<len;++i) {    
            a[i]=(ll)a[i]*iv%mod;  
        }
    }
}     
void init() {
    pw[0]=1;
    for(int i=1;i<N;++i) {
        pw[i]=(ll)pw[i-1]*2%mod;
    }
    a[0]=a[1]=1;
    for(int i=2;i<N;++i) {
        a[i]=(ll)(6*i-3)*a[i-1]%mod;
        (a[i]+=(ll)(mod-(ll)(i-2)*a[i-2]%mod)%mod)%=mod;
        a[i]=(ll)a[i]*get_inv(i+1)%mod;
    }
    f[2]=2;
    for(int i=3;i<N;++i) {
        f[i]=(ll)a[i-2]*pw[i]%mod;
    }
}   
int main() {
    // setIO("input");
    init();
    scanf("%d",&n);
    for(int i=0;i<n;++i) {
        scanf("%d",&val[i]);   
    }   
    for(int i=0;i<n;++i) { 
        A[i]=val[i];  
        B[i]=val[n-1-i];  
    }
    int lim; 
    for(lim=1;lim<=2*n;lim<<=1);   
    NTT(A,lim,1),NTT(B,lim,1);  
    for(int i=0;i<lim;++i) { 
        A[i]=(ll)A[i]*B[i]%mod; 
    }
    NTT(A,lim,-1);      
    int ans=0,inv2=get_inv(4); 
    for(int i=1;i<n;++i) { 
        int x=i+1;  
        int y=n-x+2;   
        (ans+=(ll)A[i+n-1]*f[x]%mod*f[y]%mod*inv2%mod)%=mod; 
    } 
    printf("%d\n",(ll)ans*get_inv(f[n])%mod);
    return 0;
}

  

基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值