一定要用多模数吗?如果不用,那么求条:
#include<iostream>
#include<vector>
#include<algorithm>
#define endl "\n"
#define int long long
using namespace std;
const int N=5e5+5,mod=998244353;
int a[N],r[N],m,bi,qq[N],n,q,ans[N];
vector<int> vec[N],oo[N];int cn;
bool vis[N];
int A[N],B[N];
int power(int x,int y){
int ans=1;
while(y){
if(y&1)ans=ans*x%mod;
x=x*x%mod;
y>>=1;
}
return ans;
}
void NTT(int a[],int tp){
for(int i=0;i<m;i++)if(i<r[i])swap(a[i],a[r[i]]);
for(int mid=1;mid<m;mid=mid<<1){
int w=power((tp==1?3:power(3,mod-2)),(mod-1)/(mid<<1));
for(int i=0;i<m;i+=(mid<<1)){
for(int j=0,g=1;j<mid;j++,g=g*w%mod){
int x=a[i+j],y=a[i+j+mid]*g%mod;
a[i+j]=(x+y)%mod,a[i+j+mid]=(x-y+mod)%mod;
}
}
}
}
void goo(int n){
bi=0;
while((1<<bi)<=n)bi++;
for(int i=0;i<(m=(1<<bi));i++)r[i]=(r[i>>1]>>1)|((i&1)<<bi-1);
}
void solve(vector<int> v){
int M=v.size();
goo(3*M);
for(int i=0;i<M;i++)A[i]=v[i];
reverse(A,A+M);
for(int i=0;i<M;i++)B[i]=B[i+M]=v[i];
NTT(A,1),NTT(B,1);
for(int i=0;i<m;i++)A[i]=A[i]*B[i]%mod;
NTT(A,-1);
for(int i=0;i<m;i++)A[i]=A[i]*power(m,mod-2)%mod;
if(oo[M].empty())oo[M].resize(M+2);
for(int i=0;i<M;i++)oo[M][i]+=A[i+M-1];
for(int i=0;i<m;i++)A[i]=B[i]=0;
}
signed main(){
cin.tie(0);cout.tie(0);
ios::sync_with_stdio(false);
cin>>n>>q;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
if(vis[i])continue;
int now=i;cn++;
do vec[cn].push_back(now),vis[now]=true;
while((now=a[now])!=i);
}
for(int i=1;i<=q;i++)cin>>qq[i];
for(int i=1;i<=cn;i++)solve(vec[i]);
for(int i=1;i<=n;i++){
if(oo[i].empty())continue;
for(int j=1;j<=q;j++)ans[j]+=oo[i][qq[j]%i];
}
for(int i=1;i<=q;i++)cout<<ans[i]<<endl;
}