zoukankan      html  css  js  c++  java
  • HDU5593 ZYB's Tree 树形DP +分治

    感觉其实就是树分治,一次BC的题,感觉这次题目质量比较高,仅代表蒟蒻的看法

    一次DFS获取每个点到子树的距离不大于K的点的个数,

    然后一遍BFS获取从每个点父亲不大于K的的个数,层层扩展,还是想说 其实就是树分治。。。。。并没有什么DP

    /*
    Problem : 5593 ( ZYB's Tree )     Judge Status : Accepted
    RunId : 15764784    Language : G++    Author : qianbi08
    */
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<string>
    #include<iostream>
    #include<cstdlib>
    #include<queue>
    using namespace std;
    const int maxn=500005;
    int head[maxn],fa[maxn],p;
    int dp[maxn][11],n,k,a,b;
    struct Edge
    {
        int v,next;
    }edge[maxn*2];
    void addedge(int u,int v)
    {
        edge[p].v=v;
        edge[p].next=head[u];
        head[u]=p++;
    }
    void dfs(int u)
    {
        dp[u][0]=1;
        for(int i=head[u];~i;i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==fa[u])continue;
            dfs(v);
            for(int j=1;j<=k;j++)
             dp[u][j]+=dp[v][j-1];
        }
    }
    queue<int>q;
    void bfs()
    {
       while(!q.empty())q.pop();
       for(int i=head[1];~i;i=edge[i].next)
           q.push(edge[i].v);
       while(!q.empty())
       {
           int u=q.front();
           q.pop();
           for(int i=k;i>1;--i)
            dp[u][i]+=dp[fa[u]][i-1]-dp[u][i-2];
           ++dp[u][1];
           for(int i=head[u];~i;i=edge[i].next)
              if(edge[i].v!=fa[u])q.push(edge[i].v);
       }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d%d",&n,&k,&a,&b);
            memset(head,-1,sizeof(head));
            memset(dp,0,sizeof(dp));
            p=0;
            fa[1]=0;
            long long aa=a;
            for(int i=2;i<=n;i++)
            {
                aa+=a;
                int u=(aa+b)%(i-1)+1;
                int v=i;
                fa[v]=u;
                addedge(u,v);
                addedge(v,u);
            }
            dfs(1);
            bfs();
            int ans;
            for(int i=1;i<=n;i++)
            {
               int sum=0;
               for(int j=0;j<=k;j++)
                sum+=dp[i][j];
               if(i==1)ans=sum;
               else ans^=sum;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    常用函数
    MySQL查询
    mysql的数据类型
    swoole简单demo测试
    linux下搭建lamp环境以及安装swoole扩展
    Linux下NAT模式和桥接模式的网络配置
    PhpStorm+xdebug+postman调试
    windows Apache 环境下配置支持HTTPS的SSL证书
    Yii2 restful api创建,认证授权以及速率控制
    Windows下开启composer镜像服务来安装yii
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5023310.html
Copyright © 2011-2022 走看看