题解:P16157 [ICPC 2016 NAIPC] K-Inversions
lailai0916 · · 题解
题意简述
给定只含字符
解题思路
把字符串下标改成从
这是两个
构造多项式:
再把
一对位置
因此,当
使用 NTT 求出两个多项式的卷积。
最高次数为
对固定的
时间复杂度为
参考代码
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=1<<21;
const int mod=998244353;
const int g=3;
int a[N],b[N];
ll Pow(ll x,ll y)
{
x%=mod;
ll res=1;
while(y)
{
if(y&1)res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
void ntt(int a[],int n,bool op)
{
for(int i=1,j=0;i<n;i++)
{
int k=n>>1;
while(j>=k)
{
j-=k;
k>>=1;
}
j+=k;
if(i<j)swap(a[i],a[j]);
}
for(int i=2;i<=n;i<<=1)
{
int w=Pow(g,(mod-1)/i);
if(!op)w=Pow(w,mod-2);
for(int j=0;j<n;j+=i)
{
ll x=1;
for(int k=0;k<i/2;k++)
{
int u=a[j+k];
int v=int(x*a[j+k+i/2]%mod);
a[j+k]=u+v<mod?u+v:u+v-mod;
a[j+k+i/2]=u-v<0?u-v+mod:u-v;
x=x*w%mod;
}
}
}
if(!op)
{
int inv=Pow(n,mod-2);
for(int i=0;i<n;i++)a[i]=int((ll)a[i]*inv%mod);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin>>s;
int n=s.size();
for(int i=0;i<n;i++)
{
if(s[i]=='B')a[i]=1;
else b[n-1-i]=1;
}
int len=1;
while(len<n+n-1)len<<=1;
ntt(a,len,1);
ntt(b,len,1);
for(int i=0;i<len;i++)a[i]=int((ll)a[i]*b[i]%mod);
ntt(a,len,0);
for(int i=1;i<n;i++)cout<<a[n-1-i]<<'\n';
return 0;
}