QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#199998#4483. Count Setyiyiyi#AC ✓3458ms84624kbC++172.6kb2023-10-04 15:00:182023-10-04 15:00:19

Judging History

你现在查看的是最新测评结果

  • [2023-10-04 15:00:19]
  • 评测
  • 测评结果:AC
  • 用时:3458ms
  • 内存:84624kb
  • [2023-10-04 15:00:18]
  • 提交

answer

#include<bits/stdc++.h>
#define ll long long
#define rep(i,s,t) for(int i=(s);i<=(t);i++)
#define rev_rep(i,s,t) for(int i=(s);i>=(t);i--)
using namespace std;
int ci(){
	int x; scanf("%d",&x); return x;
}

enum{N=1000023};

const int mod = 998244353;

ll qpow(ll a,ll b,int mod=mod){
	ll ans = 1;
	for(; b; b>>=1,a=a*a%mod) if( b&1 ){
		ans = ans*a%mod;
	} return ans;
}
ll inv(ll x,int mod=mod){ return qpow(x,mod-2,mod); }

using Poly = vector<ll>;
constexpr int set2(int n){ return 1<<((int)log2(n-1)+1); }
const ll g0 = 3;
const ll invg0 = inv(g0);
int init_rev_n;
vector<int> rev(set2(N*4));
void init_rev(int n){
	if( init_rev_n==n ) return ;
	rev.resize(init_rev_n = n); int t = log2(n);
	rep(i,1,n-1) rev[i] = (rev[i>>1]>>1)|((i&1)<<(t-1));
}
void NTT(Poly&A,int IDFT){
	int n = A.size(); init_rev(n);
	rep(i,1,n-1) if( i<rev[i] ) swap(A[i],A[rev[i]]);
	for(int t=1; t<n; t<<=1){
		ll w0 = qpow(IDFT==-1?invg0:g0,(mod-1)/(t*2));
		for(int l=0; l<n ; l+=t*2){
			for(int i=0, w=1; i<t ; i++,w=w*w0%mod){
				ll x = A[l+i], y = w*A[l+t+i];
				A[l+i] = (x+y)%mod;
				A[l+t+i] = (x-y)%mod;
			}
		}
	}
	if( IDFT==-1 ){
		ll invn = inv(n);
		rep(i,0,n-1) A[i] = A[i]*invn%mod;
	}
}

Poly MUL(Poly A, Poly B){
	int n = A.size()+B.size()-1, t = set2(n);
	A.resize(t), NTT(A,1);
	B.resize(t), NTT(B,1);
	rep(i,0,t-1) A[i] = A[i]*B[i]%mod;
	NTT(A,-1), A.resize(n);
	return A;
}

Poly f[N];
Poly solve(int l, int r){
	if( l==r ) return f[l];
	int mid = (l+r)/2;
	return MUL(solve(l,mid), solve(mid+1,r));
}

ll fac[N],facInv[N];
void init_fac(int n){
	fac[0] = 1;
	rep(i,1,n) fac[i]=fac[i-1]*i%mod;
	facInv[n] = inv(fac[n]);
	rev_rep(i,n,1) facInv[i-1]=facInv[i]*i%mod;
}
ll comp(ll n,ll m){
	if( m<0 || n<m ) return 0;
	return fac[n]*facInv[m]%mod*facInv[n-m]%mod;
}

bool vis[N];
int a[N];
int dfs(int u){
	if( vis[u] ) return 0;
	vis[u] = 1;
	return dfs(a[u])+1;
}

signed main(){
	//	init_fac(1000);
	//rep(nn,1,10){
	//	rep(i,0,nn/2) printf("%lld ", (comp(nn+1-i, i)-comp(nn-1-i, i-2))%mod);
	//	puts("");
	//}
	int T = ci();
	while( T-- ){
		int n = ci(), k = ci();
		rep(i,1,n) a[i] = ci();
		init_fac(n+10);
		rep(i,1,n) vis[i] = 0;
		int tot = 0;
		rep(i,1,n) if( vis[i]==0 ){
			int nn = dfs(i);
			tot++;
			f[tot].clear();
			rep(j,0,nn/2) f[tot].push_back((comp(nn+1-j, j)-comp(nn-1-j, j-2))%mod);
		}
		//rep(t,1,tot){
		//rep(i,0,(int)f[t].size()-1) printf("%lld ", f[t][i]); puts("");
		//}
		//printf("line %d:\n", __LINE__);
		Poly ans = solve(1,tot);
		if( k>=ans.size() ) puts("0");
		else printf("%lld\n", (ans[k]+mod)%mod);
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3458ms
memory: 84624kb

input:

14
5 1
5 3 2 1 4
5 2
2 5 1 3 4
10 3
10 9 3 8 6 4 5 7 2 1
30 5
1 16 28 30 27 23 2 20 10 12 7 13 11 15 17 24 14 25 21 4 22 29 3 6 19 18 8 26 9 5
30 5
29 6 21 30 14 18 24 26 3 11 23 13 2 12 16 9 4 22 25 20 28 19 5 17 8 10 15 1 7 27
500000 200000
293510 102358 252396 467703 280403 93120 462332 442364 31...

output:

5
5
40
51129
51359
371836159
565197945
0
0
844811446
803690398
638630160
14371218
1

result:

ok 14 lines