萌新玄关求助
查看原帖
萌新玄关求助
795163
coderjmc楼主2025/7/23 10:10

一定要用多模数吗?如果不用,那么求条:

#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;
}
2025/7/23 10:10
加载中...