其实这三道题都是不错的……(虽然感觉第三题略套路了……)
分别写一下做法好了……
这个就很简单了,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 }