主席花費1sec秒的題,我看着主席的題解想了一年。。
考慮容斥其中大於或小於其中一個限制,推式子,然後上分治fft優化。
具體的Orz主席https://www.cnblogs.com/Mr-Spade/p/11115654.html
附對着主席題解的蒟蒻學習筆記:
代碼:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+100,M=N*8;
const ll mod=998244353;
int n,bl[N];
ll f[N],fac[N],ifac[N];
bool a[N];
char S[N];
ll qpow(ll x,ll y=mod-2)
{
ll res=1;
while(y)
{
if(y&1)res=res*x%mod;
x=x*x%mod,y>>=1;
}
return res;
}
inline ll Add(ll x,ll y)
{return (x+y)%mod;}
inline ll Sub(ll x,ll y)
{return (x-y+mod)%mod;}
inline ll Mul(ll x,ll y)
{return x*y%mod;}
inline ll div(ll x,ll y)
{return x*qpow(y)%mod;}
ll F[M],G[M];
int wh[M],len,cc;
void ntt(ll *a,bool inv)
{
for(int i=0;i<len;i++)
if(i<wh[i])swap(a[i],a[wh[i]]);
ll tp,mo,ha;
for(int l=2,md;l<=len;l<<=1)
{
md=l>>1,tp=qpow(3,(mod-1)/l);
for(int i=0;i<len;i+=l)
{
mo=1;
for(int j=0;j<md;j++,mo=Mul(mo,tp))
{
ha=Mul(a[i+j+md],mo);
a[i+j+md]=Sub(a[i+j],ha);
a[i+j]=Add(a[i+j],ha);
}
}
}
if(inv)
{
tp=qpow(len);
for(int i=1;i<len/2;i++)swap(a[i],a[len-i]);
for(int i=0;i<len;i++)a[i]=Mul(a[i],tp);
}
}
void pre_ntt(int le)
{
cc=0,len=1;
while(len<=le)len<<=1,++cc;
for(int i=1;i<len;i++)
wh[i]=(wh[i>>1]>>1)|((i&1)<<(cc-1));
for(int i=0;i<len;i++)F[i]=G[i]=0;
}
void sol(int l,int r)
{
if(l==r)
{
if(l==0)return;
if(bl[l]==1)f[l]=mod-f[l];
return;
}
int mid=(l+r)>>1;
sol(l,mid);
pre_ntt(r-l+mid-l);
for(int i=l;i<=mid;i++)
F[i-l]=Mul(f[i],Mul(a[i],bl[i]));
for(int i=1;i<=r-l;i++)
G[i]=ifac[i];
ntt(F,0),ntt(G,0);
for(int i=0;i<len;i++)F[i]=Mul(F[i],G[i]);
ntt(F,1);
for(int i=mid+1;i<=r;i++)
f[i]=Add(f[i],F[i-l]);
sol(mid+1,r);
}
int main()
{
//freopen("37.txt","r",stdin);
fac[0]=1;
for(int i=1;i<N;i++)
fac[i]=Mul(fac[i-1],i);
ifac[N-1]=qpow(fac[N-1]);
for(int i=N-2;i>=0;i--)
ifac[i]=Mul(ifac[i+1],i+1);
scanf("%s",S+1);
n=strlen(S+1);
a[0]=1;
for(int i=1;i<=n;i++)
{
if(S[i]=='>')a[i]=1;
else a[i]=0;
}
ll nw=mod-1;
for(int i=1;i<=n;i++)
{
bl[i]=nw;
if(S[i]=='>')nw=mod-nw;
}
bl[0]=1,bl[n+1]=nw,f[0]=1;
sol(0,n+1);
printf("%lld\n",Mul(f[n+1],fac[n+1]));
}