当前位置: 首页 > news >正文

LOJ #2058「TJOI / HEOI2016」求和

不错的推柿子题

LOJ #2058

题意:求$\sum\limits_{i=0}^n\sum\limits_{j=0}^nS(i,j)·2^j·j!$其中$ S(n,m)$是第二类斯特林数


$ Solution:$

首先考虑第二类斯特林数的意义:将$ n$个有标号元素放入$ m$个无标号集合(无空集)的方案数

我们枚举空集的数量容斥:$ S(n,m)=\frac{1}{m!}\sum\limits_{k=0}^m(-1)^kC_m^k(m-k)^n$

乘上$ \frac{1}{m!}$是因为容斥的集合带标号而斯特林数本身不带标号

这样可以将原式展开得:

$ \sum\limits_{i=0}^n \sum\limits_{j=0}^n2^j \sum\limits_{k=0}^j(-1)^kC_j^k(j-k)^i$     (消阶乘项)

把组合数展开得$ \sum\limits_{i=0}^n \sum\limits_{j=0}^n 2^j j! \sum\limits_{k=0}^j \frac{(-1)^k}{k!} \frac{(j-k)^i}{(j-k)!}$

改变枚举顺序得$ \sum\limits_{j=0}^n 2^j j! \sum\limits_{k=0}^j \frac{(-1)^k}{k!} \frac{ \sum\limits_{i=0}^n (j-k)^i}{(j-k)!}$

令$ A(x)= \frac{(-1)^x}{x!}$,$ B(x)=\frac{ \sum\limits_{i=0}^n x^i}{x!}$

则原式为$ \sum\limits_{j=0}^n 2^j j! \sum\limits_{k=0}^jA(k)B(j-k)$

容易发现这是一个卷积形式,而函数$ A,B$均可以在$ O(n)$时间复杂度内完成

这样可以直接用$ NTT$优化,时间复杂度:$ O(n \ log \  n)$


 

$ my \ code:$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define p 998244353
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
    ll x = 0; char zf = 1; char ch = getchar();
    while (ch != '-' && !isdigit(ch)) ch = getchar();
    if (ch == '-') zf = -1, ch = getchar();
    while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); return x * zf;
}
void write(ll y){if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}
void writeln(const ll y){write(y);putchar('\n');}
int i,j,k,m,n,x,y,z,cnt;
int inv[100010],jc[100010],njc[100010];
int ksm(int x,int y){
    int ans=1;
    for(rt i=y;i;i>>=1,x=1ll*x*x%p)if(i&1)ans=1ll*ans*x%p;
    return ans;
}
vector<int>A,B,f,R;int lim=1;
int calc(int x,int L,int R){
    if(x==1)return R-L+1;
    return 1ll*(ksm(x,R+1)-ksm(x,L))*ksm(x-1,p-2)%p;
}
void init(int n){
    for(rt i=0;i<=1;i++)inv[i]=jc[i]=njc[i]=1;
    for(rt i=2;i<=n;i++){
        jc[i]=1ll*jc[i-1]*i%p;
        inv[i]=1ll*inv[p%i]*(p-p/i)%p;
        njc[i]=1ll*njc[i-1]*inv[i]%p;
    }    
    while(lim<=n+n)lim<<=1;
    A.resize(lim);B.resize(lim);f.resize(lim);
    A[0]=1;for(rt i=1,tag=-1;i<=n;i++,tag*=-1)A[i]=tag*njc[i];    
    B[0]=1;for(rt i=1;i<=n;i++)B[i]=1ll*njc[i]*calc(i,0,n)%p;
}
namespace poly{
    void getR(int n){
        R.resize(n);
        for(rt i=1;i<n;i++)R[i]=(R[i>>1]>>1)|(i&1)*(n>>1);
    }
    void NTT(int n,vector<int>&A,int fla){
        for(rt i=0;i<n;i++)if(i>R[i])swap(A[i],A[R[i]]);
        for(rt i=1;i<n;i<<=1){
            int w=ksm(3,(p-1)/2/i);
            for(rt j=0;j<n;j+=i<<1){
                int K=1;
                for(rt k=0;k<i;k++,K=1ll*K*w%p){
                    int x=A[j+k],y=1ll*K*A[i+j+k]%p;
                    A[j+k]=(x+y)%p,A[i+j+k]=(x-y)%p;
                }
            }
        }
        if(fla==-1){
            reverse(A.begin()+1,A.end());int invn=ksm(n,p-2);
            for(rt i=0;i<n;i++)A[i]=1ll*A[i]*invn%p;
        }
    }
}
using namespace poly;
int main(){
    n=read();init(n);
    int ans=0;getR(lim);
    NTT(lim,A,1);NTT(lim,B,1);
    for(rt i=0;i<lim;i++)f[i]=1ll*A[i]*B[i]%p;
    NTT(lim,f,-1);
    for(rt i=0;i<=n;i++)(ans+=1ll*ksm(2,i)*jc[i]%p*f[i]%p)%=p;
    cout<<(ans+p)%p;
    return 0;
}

 

转载于:https://www.cnblogs.com/DreamlessDreams/p/10054950.html

相关文章:

  • Java核心(五)深入理解BIO、NIO、AIO
  • 苏宁:我们开发百度小程序遇到的那些“坑”
  • EVCache缓存在 Spring Boot中的实战
  • php标签语句
  • 服务器基础知识
  • laravel with 查询列表限制条数
  • 进程与线程(三)——进程/线程间通信
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • c/c++再学习:查找算法了解
  • MFC限制edit控件的字符输入长度
  • Developing avb
  • 12
  • 「镁客早报」苹果HomePod音箱国行版明年国内推出,售价2799;一加与英国最大移动运营商EE达成战略合作...
  • HomeBrew及HomeBrew Cask的简介和使用
  • Python开发环境配置
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • Apache Pulsar 2.1 重磅发布
  • bootstrap创建登录注册页面
  • Brief introduction of how to 'Call, Apply and Bind'
  • Fabric架构演变之路
  • iOS 颜色设置看我就够了
  • Java|序列化异常StreamCorruptedException的解决方法
  • Node + FFmpeg 实现Canvas动画导出视频
  • scala基础语法(二)
  • Vue 动态创建 component
  • Vue.js 移动端适配之 vw 解决方案
  • vue学习系列(二)vue-cli
  • yii2中session跨域名的问题
  • 后端_ThinkPHP5
  • 前嗅ForeSpider中数据浏览界面介绍
  • 思否第一天
  • 突破自己的技术思维
  • 延迟脚本的方式
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • #stm32驱动外设模块总结w5500模块
  • #在 README.md 中生成项目目录结构
  • (11)MSP430F5529 定时器B
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (function(){})()的分步解析
  • (pytorch进阶之路)扩散概率模型
  • (solr系列:一)使用tomcat部署solr服务
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (强烈推荐)移动端音视频从零到上手(上)
  • (十八)三元表达式和列表解析
  • (转)Sublime Text3配置Lua运行环境
  • (转载)hibernate缓存
  • (转载)深入super,看Python如何解决钻石继承难题
  • ***详解账号泄露:全球约1亿用户已泄露
  • .apk文件,IIS不支持下载解决
  • .axf 转化 .bin文件 的方法
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET设计模式(11):组合模式(Composite Pattern)
  • .net中生成excel后调整宽度