QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#820480#4483. Count SetSGColinAC ✓1283ms35860kbC++202.9kb2024-12-18 21:35:112024-12-18 21:35:11

Judging History

This is the latest submission verdict.

  • [2024-12-18 21:35:11]
  • Judged
  • Verdict: AC
  • Time: 1283ms
  • Memory: 35860kb
  • [2024-12-18 21:35:11]
  • Submitted

answer

#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long LL;typedef vector<int> PN;
const int maxn=500000,maxt=1<<18,MOD=998244353;

int te,n,K,a[maxn+5],ti,vis[maxn+5];
int INV[maxn+5],fac[maxn+5];
int wn[maxt+5];
int m;PN p[maxn+5],P;

#define EOLN(x) ((x)==10 || (x)==13 || (x)==EOF)
inline char readc(){
	static char buf[100000],*l=buf,*r=buf;
	return l==r && (r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
}
template<typename T> int readi(T &x){
	T tot=0;char ch=readc(),lst='+';
	while (!isdigit(ch)) {if (ch==EOF) return EOF;lst=ch;ch=readc();}
	while (isdigit(ch)) tot=(tot<<3)+(tot<<1)+(ch^48),ch=readc();
	lst=='-'?x=-tot:x=tot;return EOLN(ch);
}
inline int ADD(int x,int y) {return x+y>=MOD?x+y-MOD:x+y;}
inline int MUL(int x,int y) {return (LL)x*y%MOD;}
int Pow(int w,int b) {int s;for (s=1;b;b>>=1,w=MUL(w,w)) if (b&1) s=MUL(s,w);return s;}
void NTTPre(){
	int x=Pow(3,(MOD-1)/maxt);
	wn[maxt/2]=1;
	for (int i=maxt/2+1;i<maxt;i++) wn[i]=MUL(wn[i-1],x);
	for (int i=maxt/2-1;i>=0;i--) wn[i]=wn[i<<1];
}
void NTT(int *a,int n,int f){
	if (f>0){
		for (int k=n>>1;k;k>>=1)
			for (int i=0;i<n;i+=k<<1)
				for (int j=0;j<k;j++){
					int x=a[i+j],y=a[i+j+k];
					a[i+j+k]=MUL(x+MOD-y,wn[k+j]);
					a[i+j]=ADD(x,y);
				}
	} else {
		for (int k=1;k<n;k<<=1)
			for (int i=0;i<n;i+=k<<1)
				for (int j=0;j<k;j++){
					int x=a[i+j],y=MUL(a[i+j+k],wn[k+j]);
					a[i+j+k]=ADD(x,MOD-y);
					a[i+j]=ADD(a[i+j],y);
				}
		for (int i=0,INV=MOD-(MOD-1)/n;i<n;i++) a[i]=MUL(a[i],INV);
		reverse(a+1,a+n);
	}
}
PN operator * (const PN &a,const PN &b){
	static int A[maxt+5],B[maxt+5];static PN c;
	int n=a.size(),m=b.size(),t;
	for (t=1;t<n+m-1;t<<=1);
	for (int i=0;i<n;i++) A[i]=a[i];for (int i=n;i<t;i++) A[i]=0;
	for (int i=0;i<m;i++) B[i]=b[i];for (int i=m;i<t;i++) B[i]=0;
	NTT(A,t,1);NTT(B,t,1);
	for (int i=0;i<t;i++) A[i]=MUL(A[i],B[i]);NTT(A,t,-1);
	c.clear();for (int i=0;i<n+m-1;i++) c.push_back(A[i]);
	return c;
}
PN Solve(int L,int R) {if (L==R) return p[L];int mid=L+(R-L>>1);return Solve(L,mid)*Solve(mid+1,R);}
void Make(int n){
	INV[0]=INV[1]=1;for (int i=2;i<=n;i++) INV[i]=MUL(MOD-MOD/i,INV[MOD%i]);
	fac[0]=1;for (int i=1;i<=n;i++) fac[i]=MUL(fac[i-1],i),INV[i]=MUL(INV[i-1],INV[i]);
}
inline int C(int x,int y) {return x<y?0:MUL(fac[x],MUL(INV[y],INV[x-y]));}
inline int G(int n,int k) {return C(n-k+1,k);}
inline int F(int n,int k) {return ADD(G(n-1,k),G(n-3,k-1));}
int main(){
	NTTPre();Make(maxn);
	for (readi(te);te;te--){
		readi(n);readi(K);
		for (int i=1;i<=n;i++) readi(a[i]);
		ti++;m=0;
		for (int i=1;i<=n;i++)
			if (vis[i]<ti){
				int cnt=1;vis[i]=ti;
				for (int j=a[i];j!=i;j=a[j]) vis[j]=ti,cnt++;
				m++;p[m].clear();p[m].push_back(1);
				for (int k=1,lim=cnt/2;k<=lim;k++) p[m].push_back(F(cnt,k));
			}
		P=Solve(1,m);
		printf("%d\n",K<P.size()?P[K]:0);
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1283ms
memory: 35860kb

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