当前位置:网站首页>2022 The 4th C.Easy Counting Problem (EGF+NTT)
2022 The 4th C.Easy Counting Problem (EGF+NTT)
2022-08-05 05:11:00 【The wonderful sauce of eating peppercorns】
题意:give a charset,大小不超过10,第icharacters appear no less than ci,求字符串长度为n的方案数,至多300个询问,ci<=5000,n<=1e7
(Pictures are not copied,I don't know if the competition for money will be held==)
思路:指数生成函数
由egf定义,第k个字符的egf为 f ( k ) = ∑ c k + o o x i i ! f(k)=\sum_{c_k}^{+oo}\frac{x^i}{i!} f(k)=∑ck+ooi!xi
则答案为 [ x n n ! ] ∏ k = 1 w f ( k ) , w 为字符集大小 [\frac{x^n}{n!}]\prod_{k=1}^w{f(k)},w为字符集大小 [n!xn]∏k=1wf(k),w为字符集大小
但是n比较大,It's definitely not possible to roll directly.改写一下f(k)的形式
f ( k ) = e x p ( x ) − ∑ i = 0 c k − 1 x i i ! f(k)=exp(x)-\sum_{i=0}^{c_k-1}\frac{x^i}{i!} f(k)=exp(x)−∑i=0ck−1i!xi
可以将exp(x)看成一个整体,The final answer is in the form
∑ i = 0 w g ( i ) ∗ e x p ( x ) i = ∑ i = 0 w g ( i ) ∗ e x p ( i x ) , 其中 g ( i ) 是一个多项式 \sum_{i=0}^wg(i)*exp(x)^i=\sum_{i=0}^wg(i)*exp(ix),其中g(i)是一个多项式 ∑i=0wg(i)∗exp(x)i=∑i=0wg(i)∗exp(ix),其中g(i)是一个多项式
g(i)The maximum number of times does not exceed ∑ c i \sum{c_i} ∑ci,而exp(ix)Each coefficient of is known,Then just loop over eachg(i)The coefficient of the term is multiplied byexp(ix)Corresponding coefficients are sufficient.最后别忘了乘n!
The specific spelling can be used for referencedp的思路,设dpij表示前i个fThe formula obtained by multiplyingexp(jx)What is the coefficient of ,There is a polynomial
转移方程 d p i , j = d p i − 1 , j − d p i , j − 1 ∗ ∑ k = 0 c i − 1 x k k ! dp_{i,j}=dp_{i-1,j} - dp_{i,j-1}*\sum_{k=0}^{c_i-1}\frac{x^k}{k!} dpi,j=dpi−1,j−dpi,j−1∗∑k=0ci−1k!xk,In fact, it is just a simulation of polynomial violence,This way of thinking a little clearer.
复杂度 O ( w 2 s l o g s + q w s ) , s = ∑ c i O(w^2slogs+qws),s=\sum{ci} O(w2slogs+qws),s=∑ci
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr)
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define pii pair<int ,int >
#define pb(v) push_back(v)
#define all(v) v.begin(),v.end()
#define int long long
#define inf 0x3f3f3f3f
#define INF 0x7f7f7f7f7f7f7f7f
#define endl "\n"
#define fi first
#define se second
#define ls p<<1
#define rs p<<1|1
#define lson p<<1,l,mid
#define rson p<<1|1,mid+1,r
#define AC return 0
#define ldb long double
const int maxn = 6e6+10;
const int p = 998244353;
const int mod = 998244353;
int Pow(int x,int d){
int tans = 1;
if(d == 0)return 1%p;
int a = Pow(x,d/2);
tans = 1ll*a*a%p;
if(d%2)tans = 1ll*tans*x%p;
return tans%p;
}
typedef vector<int> Poly;//多项式定义
inline Poly operator + (const Poly&A ,const Poly&B){
Poly res (max(A.size(),B.size()),0);
for(int i=0 ;i<max(A.size(),B.size()) ;i++){
if( i < A.size() && i<B.size() ) res[i] = (A[i]+B[i])%mod;
else if( i >= A.size() ){
res[i] = B[i];
}
else res[i] = A[i];
}
return res;
}
inline Poly operator - (const Poly&A ,const Poly&B){
Poly res (max(A.size(),B.size()),0);
for(int i=0 ;i<max(A.size(),B.size()) ;i++){
if( i < A.size() && i<B.size() ) res[i] = (A[i]-B[i]+mod)%mod;
else if( i >= A.size() ){
res[i] = (mod-B[i])%mod;
}
else res[i] = A[i];
}
return res;
}
int F1[maxn],F2[maxn];
int rev[maxn];
void NTT(int * A,int lim,int opt) {
int i, j, k, m, gn, g, tmp;
for(int i = 0; i < lim; ++i)rev[i] = (i & 1)*(lim >> 1) + (rev[i >> 1] >> 1);
for(i = 0; i < lim; ++i)if (rev[i] < i) swap(A[i], A[rev[i]]);
for(m = 2; m <= lim; m <<= 1) {
k = m >> 1;
gn = Pow(3,(p - 1) / m);
for(i = 0; i < lim; i += m) {
g = 1;
for (j = 0; j < k; ++j, g = 1ll * g * gn % p) {
tmp = 1ll * A[i + j + k] * g % p;
A[i + j + k] = (A[i + j] - tmp + p) % p;
A[i + j] = (A[i + j] + tmp) % p;
}
}
}
if(opt == -1){
reverse(A+1,A+lim);
int inv = Pow(lim,p-2);
for(i = 0; i < lim; ++i) A[i] = 1ll * A[i] * inv % p;
}
}
Poly mul(const Poly & A,const Poly & B){
int n = A.size(),m = B.size();
int siz = n + m - 1;
Poly C(siz);
if(siz < 64){
//小于等于64项直接暴力算
for(int i = 0;i < n;i++){
for(int j = 0;j < m;j++)C[i+j] = (C[i+j] + 1LL*A[i]*B[j]%p)%p;
}
return C;
}
int fsiz = 1;
while(fsiz <= siz)fsiz *= 2;
for(int i = 0;i < fsiz;i++)F1[i] = F2[i] = 0;
for(int i = 0;i < n;i++)F1[i] = A[i];
for(int i = 0;i < m;i++)F2[i] = B[i];
NTT(F1,fsiz,1);
NTT(F2,fsiz,1);
for(int i = 0;i < fsiz;i++)F1[i] = 1ll*F1[i]*F2[i]%p;
NTT(F1,fsiz,-1);
for(int i = 0;i < siz;i++){
C[i] = F1[i];
}
return C;
}
const int N = 5e5+10;
const int M = 1e7+5;
int W,n;
int c[11],fac[M],ni_f[M];
int mi[11][M];
Poly f[11][11];
ll qsm(int a,int b){
a %= mod;
ll ans=1,tmp=a;
while( b ){
if( b&1 ) ans = (ans * tmp)%mod;
tmp = tmp * tmp%mod;
b>>=1;
}
return ans;
}
void ini(){
int mx = 1e7;
fac[0]=1;
_for(i,1,mx) fac[i] = fac[i-1]*i%mod;
ni_f[mx] = qsm(fac[mx],mod-2);
_rep(i,mx-1,0) ni_f[i] = ni_f[i+1]*(i+1)%mod;
}
int S;
void ff(Poly F){
F.resize(min(S+1,(int)F.size()));
}
void solve(){
f[1][1].resize(1,1);
f[1][0].resize(c[1]+1,0);
_for(i,0,c[1]-1){
f[1][0][i] = (mod-ni_f[i])%mod;
}
_for(i,2,W){
_for(j,0,i){
Poly t (c[i]+1,0);
_for(k,0,c[i]-1){
t[k] = (mod-ni_f[k])%mod;
}
f[i][0] = mul(f[i-1][0],t);
ff(f[i][0]);
f[i][j] = (f[i-1][j-1] + mul(f[i-1][j],t));
ff(f[i][j]);
}
}
}
int Q(int n){
int ans=0;
for(int i=0 ;i<=W ;i++){
// exp(ix)
int pw = qsm(i,n-min(n,(int)f[W][i].size()-1ll));
for(int j=min(n,(int)f[W][i].size()-1ll) ;j>=0 ;j--){
int t = n-j;
if( j < min(n,(int)f[W][i].size()-1ll) ) pw = pw * i%mod;
ans = (ans + f[W][i][j] * pw %mod*ni_f[t]%mod)%mod;
}
}
return ans*fac[n]%mod;
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
IOS;
cin>>W;
_for(i,1,W) cin>>c[i];
S = accumulate(c+1,c+1+W,0ll);
ini();
solve();
int q;cin>>q;
while( q-- ){
int x;cin>>x;
int ans = Q(x);
cout<<ans<<endl;
}
AC;
}
边栏推荐
- Judgment statement _switch and case
- Flutter learning - the beginning
- 使用二维码解决固定资产管理的难题
- 请写出SparkSQL语句
- 重新审视分布式系统:永远不会有完美的一致性方案……
- Flutter真机运行及模拟器运行
- Dephi reverse tool Dede exports function name MAP and imports it into IDA
- [Student Graduation Project] Design and Implementation of the Website Based on the Web Student Information Management System (13 pages)
- coppercam入门手册[6]
- Requests the library deployment and common function
猜你喜欢

Detailed explanation of each module of ansible

University Physics---Particle Kinematics

How can Flutter parent and child components receive click events

mutillidae download and installation

【学生毕业设计】基于web学生信息管理系统网站的设计与实现(13个页面)
![[Student Graduation Project] Design and Implementation of the Website Based on the Web Student Information Management System (13 pages)](/img/86/9c9a2541f2b7089ae47e9832fffdb3.png)
[Student Graduation Project] Design and Implementation of the Website Based on the Web Student Information Management System (13 pages)

『递归』递归概念与典型实例

Flutter 父子组件如何都能收到点击事件

Reverse theory knowledge 4

算法---一和零(Kotlin)
随机推荐
【cesium】加载并定位 3D Tileset
Dephi逆向工具Dede导出函数名MAP导入到IDA中
【软考 系统架构设计师】软件架构设计③ 特定领域软件架构(DSSA)
u-boot调试定位手段
Use IDEA to connect to TDengine server
[WeChat applet] WXML template syntax - conditional rendering
[cesium] element highlighting
mysql数据库表什么字段类型的存储长度最大?
for..in和for..of的区别
人性的弱点
使用二维码解决固定资产管理的难题
数字_获取指定位数的小数
Excel Paint
Flutter learning 5-integration-packaging-publish
【无标题】
dedecms error The each() function is deprecated
软件管理rpm
Redis - 13. Development Specifications
请写出SparkSQL语句
[Student Graduation Project] Design and Implementation of the Website Based on the Web Student Information Management System (13 pages)