answer:
80 points practice is still easy to listen to
Enumerate endpoint states for non-tree edges
However, I don't know why there is an extra point.
specific implementation
The most violent is 3^n times, but we can find that for i not taking, j taking i and not taking, j not taking can be equivalent to i not taking, j has no limit, this is 2^n
Or just let it be the same as C(n,1)+C(n,2)...=2^n
100pts should be a virtual tree to deal with the coefficient.
Code:
#include <bits/stdc++.h> using namespace std; #define N 300000 #define rg register #define mo 998244353 #define ll long long struct re{ int a,b; }a[N],ts[15]; const int n2=1e7; int head[N],l2,l,v[N],n,m,hash[n2]; ll dp[N][2],ans; bool f[N],ff[N]; inline void arr(int x,int y) { a[++l].a=head[x]; a[l].b=y; head[x]=l; } inline void dfs(int x,int y) { rg int u=head[x]; f[x]=1; while (u) { rg int v=a[u].b; if (u!=y) { if (f[v]) { if (!ff[u]) { ts [ ++ l2] .a = a [u] .b; ts[l2].b=x; ff[u] = 1 ; ff[u % 2 ?u+ 1 :u- 1 ]= 1 ; } } else dfs(v,u%2?u+1:u-1); } u=a[u].a; } } inline void dfs3(rg int x,rg int y) { rg int u=head[x]; dp[x][0]=1; dp[x][1]=1; if (v[x]==1) dp[x][0]=0; if (v[x]==-1) dp[x][1]=0; while (u) { rg int v=a[u].b; if (u!=y&&!ff[u]) { dfs3(v,u % 2 ?u+ 1 :u- 1 ); dp[x][1]*=dp[v][0]; dp[x][ 1 ]%= mo; dp[x][0]*=(dp[v][0]+dp[v][1]); dp[x][ 0 ]%= mo; } u=a[u].a; } } const int mo1=9e6+7; inline void dfs2(rg int now) { if (now==0) { memset(dp,0,sizeof(dp)); dfs3(1,0); ans+=dp[1][0]+dp[1][1]; ans%=mo; return; } rg int x=ts[now].a,y=ts[now].b; rg int tmp1=v[x],tmp2=v[y]; if (v[x]!=1&&v[y]!=-1) { v [x] = - 1 ; v [y] = 1 ; dfs2 (now- 1 ); v [x] = tmp1; v [y] = tmp2; } if (v[y]!=1) { v[y]=-1; dfs2(now-1); v[y]=tmp2; } } intmain () { freopen("noi.in","r",stdin); freopen("noi.out","w",stdout); std::ios::sync_with_stdio(false); cin>>n>>m; int x,y; for (rg int i=1;i<=m;i++) { cin>>x>>y; arr(x,y); arr(y,x); } dfs(1,0); dfs2(l2); cout<<ans<<endl; return 0; }