zoukankan      html  css  js  c++  java
  • CF997D

    分析:

      假设在第一个树上我们有一个长度为x的环,在第二树上我们有一个长度为y的环,那么可以在叉积树上构造出$inom{x+y}{x}$个长度为x+y的环

      问题的关键就变成了如何统计出在一个树上的长度为i的环的个数

      设$f(u,v,k)$表示从u点出发走k步回到u点,中途不经过点v的方案数,其中v是u的相邻点

      考虑求解的转移过程,一定是从u走到某个邻接点w(w!=v),然后从w走到w(不经过u),然后再回到u,于是有转移方程

      

      这个是$O(n^2k^2)$的,但明显里面的w不需要枚举,只需要拿sum减去w=v的情况就行了,于是变成了$O(nk^2)$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mp make_pair
     4 const int maxn=4000,mod=998244353;
     5 int k;
     6 int ans;
     7 int C[80][80];
     8 void inc(int &a,int b)
     9 {
    10     a=(a+b)%mod;
    11 }
    12 struct wjmzbmr
    13 {
    14     int n;
    15     vector<int> g[maxn+5];
    16     vector<int> dp[80][maxn+5];
    17     int sum[80][maxn+5];
    18     int ans[maxn+5],sz[maxn+5];
    19     map<pair<int,int>,int> s;
    20     void init()
    21     {
    22         for(int i=1;i<n;++i)
    23         {
    24             int u,v;
    25             scanf("%d%d",&u,&v);
    26             g[u].push_back(v),g[v].push_back(u);
    27         }
    28         for(int i=1;i<=n;++i)
    29             for(int j=0;j<g[i].size();++j)
    30                 s[mp(i,g[i][j])]=j;
    31         for(int i=1;i<=n;++i) sz[i]=g[i].size(),g[i].push_back(0);
    32         for(int t=0;t<=k;++t)
    33             for(int i=0;i<=n;++i)
    34                 dp[t][i].resize(sz[i]+1,0);
    35     }
    36     void work()
    37     {
    38         for(int i=1;i<=n;++i)
    39             for(int j=0;j<=sz[i];++j)
    40             {
    41 
    42                 dp[0][i][j]=1;
    43                 inc(sum[0][g[i][j]],1);
    44             }
    45         for(int i=2;i<=k;++i)
    46             for(int u=1;u<=n;++u)
    47                 for(int j=0;j<=sz[u];++j)
    48                 {
    49                     int v;
    50                     if(j<sz[u]) v=g[u][j];else v=0;
    51                     int id;
    52                     if(v==0) id=0;
    53                     else
    54                         id=s[mp(v,u)];
    55                     for(int t=0;t<=i-2;++t)
    56                         dp[i][u][j]=((dp[i][u][j]+1LL*dp[i-t-2][u][j]*(sum[t][u]-dp[t][v][id])%mod)%mod+mod)%mod;
    57                     inc(sum[i][v],dp[i][u][j]);
    58                 }
    59         for(int i=0;i<=k;i+=2)
    60             for(int u=1;u<=n;++u)
    61                 inc(ans[i],dp[i][u][sz[u]]);
    62     }
    63 }tree[2];
    64 int main()
    65 {
    66     //freopen("ce.in","r",stdin);
    67     scanf("%d%d%d",&tree[0].n,&tree[1].n,&k);
    68     tree[0].init(),tree[1].init();
    69     tree[0].work();
    70     tree[1].work();
    71     C[0][0]=1;
    72     for(int i=1;i<=k;++i)
    73     {
    74         C[i][0]=1;
    75         for(int j=1;j<=i;++j)
    76             C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    77     }
    78     for(int i=0;i<=k;++i)
    79         inc(ans,int(1LL*tree[0].ans[i]*tree[1].ans[k-i]%mod*C[k][i]%mod));
    80     printf("%d
    ",ans);
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    jaxp对xml的增删改查
    xml&xml约束dtd&xml解析器
    meta标签&移动端常用meta标签总结
    java项目服务部署,启停脚本
    扩展欧几里得算法
    【数据结构】Huffman树
    【数据结构】堆的删除
    【数据结构】平衡二叉树的判断
    【数据结构】模拟windows资源管理器
    BFS/DFS 广度/深度优先搜索
  • 原文地址:https://www.cnblogs.com/wmrv587/p/9258527.html
Copyright © 2011-2022 走看看