其实这三道题都是不错的……(虽然感觉第三题略套路了……)

分别写一下做法好了……

COGS2392 有标号的二分图计数 I

这个就很简单了,Noip难度。

显然可以直接认为黑点和白点分别位于二分图两侧,枚举二分图左侧的点数,如果左侧的点数为$k$,那么就有$C_n^k$种选择方案,并且有$k(n-k)$条边可选,因为每条边都可以选或不选,因此答案就是

\begin{align}\sum_{k=0}^n C_n^k 2^{k(n-k)}\end{align}

由于只需求出一个答案,直接快速幂搞一搞即可,复杂度$O(n\log n)$。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define LL long long
 5 #define fac(x) (((x)<(0))?(0):(f[(x)]))
 6 using namespace std;
 7 const int maxn=100010;
 8 const LL p=998244353ll;
 9 LL inv(LL);
10 LL qpow(LL,LL);
11 LL C(int,int);
12 int n;
13 LL f[maxn<<1],ans=0;
14 int main(){
15 #define MINE
16 #ifdef MINE
17     freopen("QAQ_bipartite_one.in","r",stdin);
18     freopen("QAQ_bipartite_one.out","w",stdout);
19 #endif
20     scanf("%d",&n);
21     f[0]=1ll;
22     for(int i=1;i<=n;i++)f[i]=f[i-1]*i%p;
23     for(int i=0;i<=n;i++)(ans+=C(n,i)*qpow(2ll,(LL)(n-i)*i%(p-1ll)))%=p;
24     printf("%d",(int)ans);
25     return 0;
26 }
27 LL inv(LL x){
28     return qpow(x,p-2ll);
29 }
30 LL qpow(LL a,LL b){
31     LL ans=1ll;
32     for(;b;b>>=1,(a*=a)%=p)if(b&1ll)(ans*=a)%=p;
33     return ans;
34 }
35 LL C(int n,int m){
36     return fac(n)*inv(fac(m)*fac(n-m)%p)%p;
37 }
View Code

相关文章: