zoukankan      html  css  js  c++  java
  • #10 //I [HNOI/AHOI2018]毒瘤

    题解:

    80分做法还是听简单的

    对于非树边枚举一下端点状态

    然而我也不知道为什么就多t了一个点

    具体实现上

    最暴力的是3^n次 但是我们可以发现对于i不取,j取 i不取,j不取是可以等效成i不取,j没有限制,这样是2^n

    或者直接容斥一下搞i取j取 这样C(n,1)+C(n,2)...=2^n一样的吧

    100pts应该是虚树处理一下系数吧

    代码:

    #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;
      }
    }
    int main()
    {
      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;
    }
  • 相关阅读:
    优化SQL查询:如何写出高性能SQL语句
    提高SQL执行效率的16种方法
    Spring Ioc DI 原理
    java内存泄漏
    转:js闭包
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Best Time to Buy and Sell Stock with Cooldown
    LeetCode Length of Longest Fibonacci Subsequence
    LeetCode Divisor Game
    LeetCode Sum of Even Numbers After Queries
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8955432.html
Copyright © 2011-2022 走看看