zoukankan      html  css  js  c++  java
  • JZOJ 5913. 林下风气

    Description

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

    Input

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

    Output

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

    Sample Input

    5 3
    1 2 3 4 5
    1 2
    1 3
    2 4
    2 5

    Sample Output

    4

    Data Constraint

    对于30%的数据,n<=22
    对于另外20%的数据,树是一条链
    对于另外20%的数据,ai只有0和1两种
    对于100%的数据,N<=3333,0<=ai<=N,K>=0
     
    做法:有一个套路,所有差值<=k的联通块减去<=k-1的联通块即是答案,可以用树形dp统计。
     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #define mo 19260817
     5 #define N 7777
     6 #define LL long long
     7 using namespace std;
     8 int n,m,ls[N],tot;
     9 LL    ans,ans2;
    10 struct edge{
    11     int to,next;
    12 }e[N];
    13 
    14 struct arr{
    15     int s,num;
    16 }a[N];
    17 
    18 void add(int x,int y){
    19     e[++tot].to=y;
    20     e[tot].next=ls[x];
    21     ls[x]=tot;
    22 }
    23 
    24 void Init(){
    25     scanf("%d%d",&n,&m);
    26     for (int i=1;i<=n;i++) scanf("%d",&a[i].s),a[i].num=i;
    27     for (int i=1;i<n;i++){
    28         int u,v;
    29         scanf("%d%d",&u,&v);
    30         add(u,v);
    31         add(v,u);
    32     }
    33 }
    34 
    35 LL count(int x,int pre,int root){
    36     LL sum=1;
    37     for (int i=ls[x];i;i=e[i].next){
    38         int v=e[i].to;
    39         if (v==pre) continue;
    40         if (a[root].s-a[v].s>m||a[root].s<a[v].s) continue;
    41         if (a[root].s==a[v].s&&a[root].num<a[v].num) continue;
    42         sum=(sum*(count(v,x,root)+1))%mo;
    43     }
    44     return sum;
    45 }
    46 
    47 
    48 LL count2(int x,int pre,int root){
    49     LL sum=1;
    50     for (int i=ls[x];i;i=e[i].next){
    51         int v=e[i].to;
    52         if (v==pre) continue;
    53         if (a[root].s-a[v].s>m-1||a[root].s<a[v].s) continue;
    54         if (a[root].s==a[v].s&&a[root].num<a[v].num) continue;
    55         sum=(sum*(count2(v,x,root)+1))%mo;
    56     }
    57     return sum;
    58 }
    59 
    60 
    61 int main(){
    62     freopen("lkf.in","r",stdin);
    63     freopen("lkf.out","w",stdout);
    64     Init();
    65     for (int i=1;i<=n;i++)
    66         ans=(ans+count(i,0,i))%mo;
    67     if (m!=0){
    68         for (int i=1;i<=n;i++)
    69             ans2=(ans2+count2(i,0,i))%mo;
    70     }
    71     cout<<(ans-ans2+mo)%mo;
    72 }
    View Code
  • 相关阅读:
    欢乐送小程序自动化探索实践
    看完这篇还不了解 Nginx,那我就哭了!
    测试人的技术栈
    Bug,项目过程中的重要数据
    什么是测试开发工程师?
    hdu 1219 AC Me
    hdu 1202 The calculation of GPA(算绩点问题)
    hdu1205吃糖果(插空法)
    hdu1201(18岁生日)
    hdu1231最大连续子序列
  • 原文地址:https://www.cnblogs.com/traveller-ly/p/9818488.html
Copyright © 2011-2022 走看看