QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#199998 | #4483. Count Set | yiyiyi# | AC ✓ | 3458ms | 84624kb | C++17 | 2.6kb | 2023-10-04 15:00:18 | 2023-10-04 15:00:19 |
Judging History
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