T1 bishop

题目大意:

n个点组成了一些环 在这n个点中等概率选k个点(不能重复) 染了一个点就会染该环上的所有点

求所有点都被染色的概率

思路:

可以设$F_{i,j}$  表示在$i$个环放$k$个点的方案数即$F_{i,j}=C(i,j)$,$if \space j==0 :F_{i,j}=0$

我们考虑生成函数即合并两个数组 发现是卷积 所以我们直接建出初始数组 然后分治一样两两卷积

就过了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<vector>
 8 #include<queue>
 9 #include<map>
10 #define rep(i,s,t) for(register int i=(s);i<=(t);++i)
11 #define dwn(i,s,t) for(register int i=(s);i>=(t);--i)
12 #define ren for(int i=fst[x];i;i=nxt[i])
13 #define Fill(x,t) memset(x,t,sizeof(x))
14 #define ll long long
15 #define inf 2139062143
16 #define MAXN 170100
17 #define MOD 998244353
18 using namespace std;
19 inline int read()
20 {
21     int x=0,f=1;char ch=getchar();
22     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
23     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
24     return x*f;
25 }
26 int N,n,m,k,vis[MAXN],to[MAXN],sz[MAXN],tot;
27 int fac[MAXN],inv[MAXN],rev[MAXN<<2],inv3;
28 ll A[MAXN<<2],B[MAXN<<2],lmt,lg;
29 vector <int> vec[MAXN];
30 void dfs(int x) {sz[tot]++,vis[x]=1;if(!vis[to[x]]) dfs(to[x]);}
31 ll q_pow(ll bas,ll t,ll res=1)
32 {
33     for(;t;t>>=1,(bas*=bas)%=MOD)
34         if(t&1) (res*=bas)%=MOD;return res;
35 }
36 int C(int n,int m) {return ((ll)((((ll)fac[n]*inv[m])%MOD)*inv[n-m]))%MOD;}
37 void ntt(ll *a,int n,int f)
38 {
39     rep(i,0,n-1) if(i<rev[i])swap(a[i],a[rev[i]]);
40     for(int i=1;i<n;i<<=1)
41     {
42         ll wn=q_pow(3,(MOD-1)/(i<<1))%MOD;
43         if(f==-1)wn=q_pow(wn,MOD-2);
44         for(int j=0;j<n;j+=i<<1)
45         {
46             ll w=1,x,y;
47             for(int k=0;k<i;k++,w=wn*w%MOD)
48                 x=a[k+j],y=((ll)a[k+j+i]*w)%MOD,a[j+k]=(x+y)%MOD,a[j+k+i]=(x-y+MOD)%MOD;
49         }
50     }
51     if(f==1) return ;int nv=q_pow(n,MOD-2);
52     for(int i=0;i<n;i++) a[i]=a[i]*nv%MOD;
53 }
54 void Div(int l,int r,ll tmp)
55 {
56     if(l==r) return ;int mid=(l+r)>>1;
57     int t1=min(sz[mid]-sz[l-1],k-1),t2=min(sz[r]-sz[mid],k-1);
58     Div(l,mid,t1);Div(mid+1,r,t2);tmp=t1+t2;lmt=1,lg=0;
59     while(lmt<=tmp) lmt<<=1,lg++;
60     for(int i=0;i<lmt;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
61     rep(i,0,t1) A[i]=vec[l][i];rep(i,t1+1,lmt-1) A[i]=0;
62     rep(i,0,t2) B[i]=vec[mid+1][i];rep(i,t2+1,lmt-1) B[i]=0;/*
63     rep(i,0,lmt-1) cout<<A[i]<<" ";cout<<endl;
64     rep(i,0,lmt-1) cout<<B[i]<<" ";cout<<endl;*/
65     ntt(A,lmt,1);ntt(B,lmt,1);
66     rep(i,0,lmt) (A[i]*=B[i])%=MOD;
67     ntt(A,lmt,-1);vec[l].clear();vec[mid+1].clear();
68     rep(i,0,min(tmp,(ll)k)) vec[l].push_back(A[i]);
69 }
70 int main()
71 {
72     freopen("bishop.in","r",stdin);
73     freopen("bishop.out","w",stdout);
74     int T=read(),x;inv[0]=inv[1]=fac[0]=1;
75     rep(i,2,152501) inv[i]=((ll)(MOD-MOD/i)*inv[MOD%i])%MOD;inv3=inv[3];
76     rep(i,1,152501) fac[i]=((ll)fac[i-1]*i)%MOD,inv[i]=((ll)inv[i-1]*inv[i])%MOD;
77     while(T--)
78     {
79         Fill(vis,0);Fill(sz,0);
80         n=read(),k=read()+1,tot=0;rep(i,1,n) to[i]=read();
81         rep(i,1,n) if(!vis[i]) tot++,dfs(i);
82         x=n,n=tot;rep(i,1,n) {vec[i].push_back(0);rep(j,1,min(sz[i],k-1)) vec[i].push_back(C(sz[i],j));}
83         //rep(i,1,n) {for(auto x:vec[i]) cout<<x<<" ";puts("");}
84         rep(i,1,n) sz[i]+=sz[i-1];//cout<<sz[1]<<" "<<sz[2]<<endl;
85         Div(1,n,k);printf("%lld\n",((ll)(vec[1][k-1]*q_pow(C(x,k-1),MOD-2)))%MOD);
86         rep(i,1,n) vec[i].clear();
87     }
88     fclose(stdout);return 0;
89 }
View Code

相关文章:

  • 2021-07-06
  • 2021-12-28
  • 2021-12-15
  • 2021-06-15
  • 2021-04-02
  • 2021-08-12
  • 2021-12-25
  • 2021-05-27
猜你喜欢
  • 2021-06-18
  • 2021-06-18
  • 2021-08-19
  • 2022-12-23
  • 2022-12-23
  • 2021-04-18
相关资源
相似解决方案