#10 //I [HNOI/AHOI2018] Tumor

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;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324980865&siteId=291194637