• 10.24T1 树形DP


    1.林下风气

     (lkf)

    【问题描述】

    里口福因有林下风气,带领全国各地高校掀起了一股AK风,大家都十分痴迷于AK。里口福为了打击大家的自信心,出了一道自以为十分困难的题目。
    里口福有一棵树,第i个节点上有点权ai,他的问题就是这棵树中有多少个不同的连通块满足连通块的最大值与最小值之差=k,两个连通块不同当且仅当至少存在一个节点在一个连通块中出现而另一个连通块中没有出现。
    痴迷于AK的你马上接下这道题目,在里口福狂妄的笑声中,你切掉这道题的决心更加坚定了,现在就差你的代码了。

    【输入】

    第一行两个整数n,k,表示树的大小以及题目中的k。
    第二行n个整数,第i个整数表示ai。
    接下来n-1行,每行两个整数x,y表示树边(x,y)。

    【输出】

    一行一个整数,表示答案,答案对19260817取模。

    【样例输入】

    5 3

    1 2 3 4 5

    1 2

    1 3

    2 4

    2 5

    【样例输出】

    4

    【数据范围与约定】

    对于30%的数据,n<=22
    对于另外20%的数据,树是一条链
    对于另外20%的数据,ai只有0和1两种
    对于100%的数据,N<=3333,0<=ai<=N,K>=0

    至于转移方程看代码吧,建议粘贴到dev里面看

    code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #define N 50000
     5 using namespace std;
     6 const long long mod=19260817;
     7 long long G[N][2][2];
     8 long long f[N][2][2];
     9 long long val[N],fa[N];
    10 long long Ans=0;
    11 struct node {
    12     long long u,v;
    13 } e[N];
    14 long long first[N],nxt[N],cnt;
    15 long long n,k;
    16 void add(long long u,long long v) {
    17     e[++cnt].u=u;
    18     e[cnt].v=v;
    19     nxt[cnt]=first[u];
    20     first[u]=cnt;
    21 }
    22 void DP(long long x,long long max0) {
    23     long long min0=max0-k;
    24     f[x][0][0]=f[x][0][1]=f[x][1][0]=f[x][1][1]=0;
    25     if(val[x]==max0&&val[x]!=min0)f[x][1][0]=1;
    26     if(val[x]==min0&&val[x]!=max0)f[x][0][1]=1;
    27     if(val[x]==min0&&val[x]==max0)f[x][1][1]=1;
    28     if(val[x]>min0&&val[x]<max0)f[x][0][0]=1;
    29     for(long long i=first[x]; i; i=nxt[i]) {
    30         long long v=e[i].v;
    31         if(v!=fa[x]) {
    32             fa[v]=x;
    33             DP(v,max0);
    34             G[x][1][1]=f[x][1][1],G[x][1][0]=f[x][1][0],G[x][0][1]=f[x][0][1],G[x][0][0]=f[x][0][0];
    35             f[x][1][1]+=G[x][1][1]*(f[v][0][0]+f[v][0][1]+f[v][1][0]+f[v][1][1])+G[x][0][1]*(f[v][1][1]+f[v][1][0])+G[x][1][0]*(f[v][0][1]+f[v][1][1])+G[x][0][0]*f[v][1][1];
    36             f[x][1][0]+=G[x][1][0]*(f[v][1][0]+f[v][0][0])+G[x][0][0]*f[v][1][0];
    37             f[x][0][1]+=G[x][0][1]*(f[v][0][0]+f[v][0][1])+G[x][0][0]*f[v][0][1];
    38             f[x][0][0]+=G[x][0][0]*f[v][0][0];
    39             for(long long i=0;i<=1;i++)for(long long j=0;j<=1;j++)f[x][i][j]%=mod;
    40         }
    41 
    42     }
    43     Ans+=f[x][1][1];
    44     Ans%=mod;
    45     return;
    46 }
    47 int main() {
    48     cin>>n>>k;
    49     long long max0=0,min0=99999;
    50     for(long long i=1; i<=n; i++) {
    51         cin>>val[i];
    52         max0=max(max0,val[i]);
    53         min0=min(min0,val[i]);
    54     }
    55     for(long long i=1; i<n; i++) {
    56         long long u,v;
    57         cin>>u>>v;
    58         add(u,v);
    59         add(v,u);
    60     }
    61     for(long long i=min0+k; i<=max0; i++) {
    62         DP(1,i);
    63         Ans%=mod;
    64     }
    65     cout<<Ans;
    66     return 0;
    67 }

    over

  • 相关阅读:
    [三]JavaIO之IO体系类整体设计思路 流的概念以及四大基础分类
    [二] JavaIO之File详解 以及FileSystem WinNTFileSystem简介
    [一]FileDescriptor文件描述符 标准输入输出错误 文件描述符
    [零] JavaIO入门简介 程序设计语言 为什么需要IO库
    装饰器模式 Decorator 结构型 设计模式 (十)
    适配器模式 adapter 结构型 设计模式(九)
    layui 鼠标悬停单元格显示全部
    mysql 日期总结
    区域块路由与全局路由兼容,双重路由
    JS-SDK相关参考
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9846033.html
Copyright © 2020-2023  润新知