BZOJ4555 求和

Link

推导先放一放吧。。 这道题给我的教育很深刻:

  1. 一定要分清循环的是下标还是长度。FFT的lenlen写成了<n< n,查了很长时间
  2. 谨防填错模板函数参数的数据类型。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "lucida"
using std::swap;
using std::reverse;
const int MAXN=100000+11,P=998244353,MAXL=MAXN<<2,orig=3;
template <class T>
T pow(T base,int index) {
T res;
for(res=1;index;base*=base,index>>=1) {
if(index&1) {
res*=base;
}
}
return res;
}

namespace modint {
template <int modu> struct ModInt {
int64 num;
ModInt() {}
ModInt(int64 num):num(num%P) {}
ModInt inverse() const {
return pow(*this,modu-2);//modu-1?..
}
friend ModInt operator +(const ModInt &a,const ModInt &b) {
return ModInt(a.num+b.num);
}
friend ModInt operator -(const ModInt &a,const ModInt &b) {
return ModInt(a.num-b.num);
}
friend ModInt operator *(const ModInt &a,const ModInt &b) {
return ModInt(a.num*b.num);
}
friend ModInt operator /(const ModInt &a,const ModInt &b) {
return a*b.inverse();
}
};
}
typedef modint::ModInt<P> ModInt;
ModInt fac[MAXN];
struct _{_(){
fac[0]=1;
for(int i=1;i<MAXN;++i) {
fac[i]=fac[i-1]*i;
}
}}Auto;
void Trans(ModInt a[],int n,int d) {
for(int i=1,j=n>>1;i<n-1;++i) {
if(i<j) swap(a[i],a[j]);
int k=n>>1;
while(k<=j) {
j-=k;
k>>=1;
}
j+=k;
}
for(int len=2;len<=n;len<<=1) {//<=n?<n?.
ModInt rt=pow((ModInt)orig,(P-1)/len);//实例化了int.
//cos(2*pi*d/len),sin(2*pi*d/len)
for(int i=0;i<n;i+=len) {
ModInt w=1;
for(int j=i;j<i+(len>>1);++j) {
ModInt u=a[j],t=w*a[j+(len>>1)];
a[j]=u+t,a[j+(len>>1)]=u-t;
w*=rt;
}
}
}
if(d==-1) {
reverse(a+1,a+n);
ModInt inv=ModInt(n).inverse();
for(int i=0;i<n;++i) {
a[i]*=inv;
}
}
}
struct Polynomial {
int64 a[MAXL],n;
int64 &operator [](const int &x) {
return a[x];
}
const int64 &operator [](const int &x) const {
return a[x];
}
friend Polynomial operator *(const Polynomial &A,const Polynomial &B) {
static Polynomial C;
static ModInt a[MAXL],b[MAXL],c[MAXL];
int n=1;for(int lim=C.n=A.n+B.n-1;n<lim;n<<=1);
for(int i=0;i<n;++i) {
a[i]=i<A.n?A[i]:0;
b[i]=i<B.n?B[i]:0;
}
Trans(a,n,1);Trans(b,n,1);
for(int i=0;i<n;++i) {
c[i]=a[i]*b[i];
}
Trans(c,n,-1);
for(int i=0;i<C.n;++i) {
C[i]=c[i].num;
}
return C;
}
}A,B,C;
int main() {
freopen("input","r",stdin);
int n;is>>n;
A.n=B.n=n+1;
for(int i=0;i<=n;++i) {
A[i]=((i&1?-1:1)/fac[i]).num;
}
B[0]=1;
B[1]=n+1;
for(int i=2;i<=n;++i) {
B[i]=((1-pow((ModInt)i,n+1))/((1-i)*fac[i])).num;
}
C=A*B;
ModInt res=0;
for(int i=0;i<=n;++i) {
res+=pow(ModInt(2),i)*fac[i]*C[i];
}
int64 Ans=(res.num+P)%P;
os<<Ans<<'\n';
return 0;
}