QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#820480 | #4483. Count Set | SGColin | AC ✓ | 1283ms | 35860kb | C++20 | 2.9kb | 2024-12-18 21:35:11 | 2024-12-18 21:35:11 |
Judging History
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