• hdu 6121---Build a tree(深搜+思维)


    题目链接

    Problem Description
    HazelFan wants to build a rooted tree. The tree has n nodes labeled 0 to n1, and the father of the node labeled i is the node labeled i1k. HazelFan wonders the size of every subtree, and you just need to tell him the XOR value of these answers.
     
    Input
    The first line contains a positive integer T(1T5), denoting the number of test cases.
    For each test case:
    A single line contains two positive integers n,k(1n,k1018).
     
    Output
    For each test case:
    A single line contains a nonnegative integer, denoting the answer.
     
    Sample Input
    2
    5 2
    5 3
     
    Sample Output
    7
    6
     
     
    题意:有一颗树,节点编号0~n-1 ,节点 i 的父亲节点编号 ⌊i1k⌋ ,求所有子树大小相异或值?
     
    思路:可以发现这是一棵完全 k 叉树 ,那么所有叶子节点高度差最多为1,且所有最高层叶子都靠左。那么我们从上向下找最高最靠右的叶子,然后回溯时计算:这时当前节点子树的大小特殊,其左边的所有同层次节点子树大小相同,其右边的所有同层次节点子树大小相同,所以对于每一层只需要考虑三种不同的节点子树。
     
             官方题解:
           
     
     

    代码如下:(唉,比赛时代码没调出来,赛后才调完,有点可惜~)

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    typedef  long long LL;
    const LL N=1e18+5;
    LL cnt[70];
    LL pw[70];
    LL n,k,m;
    int deep;
    LL ans=0;
    LL L,R,mid;
    
    void dfs(int x)
    {
        if(x>deep) return ;
        dfs(x+1);
        LL pos=(cnt[x]-1)%k; ///left brother;
    
        int f=(cnt[x]-1)&1;
        if(f) ans^=L;
    
        LL cR=pw[x]-cnt[x];
        f=cR&1;
        if(f) ans^=R;
    
        ans^=mid;
    
        mid=pos*L+mid+1+(k-pos-1)*R;
        L=L*k+1;
        R=R*k+1;
    }
    
    int main()
    {
        int T; cin>>T;
        while(T--)
        {
           scanf("%lld%lld",&n,&k);
           if(k == 1){
                if(n%4 == 0) ans = n;
                else if(n%4 == 1) ans = 1;
                else if(n%4 == 2) ans = n+1;
                else if(n%4 == 3) ans = 0;
                printf("%lld
    ",ans);
                continue;
           }
           LL tmp=1;
           m=n-1; pw[0]=1;
           for(int i=1;i<70;i++)
           {
               tmp=tmp*k; pw[i]=tmp;
               if(m<tmp || tmp<0 ) {  pw[i]=N; deep=i; break; }
               m-=tmp;
           }
           cnt[deep]=m;
           if(m==0) { deep--; cnt[deep]=pw[deep]; m=cnt[deep]; }
           for(int i=deep-1;i>=0;i--)
           {
               cnt[i]=(m+k-1)/k;
               m=cnt[i];
           }
           L=1; mid=1; R=0;
           ans=0;
           dfs(0);
           printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    golang类型判断
    golang文件相对路径问题
    golang中数组与切片的区别
    golang的一些基础数据类型转换
    golang变量的注意
    Oracle数据库导入导出总结(dmp文件)
    Ajax,谷歌提示AutoCompleteExtender控件
    验证控件插图扩展控件ValidatorCalloutExtender(用于扩展验证控件)和TextBoxWatermarkExtender
    当使用母版页时JavaScript客户端获取服务器控件的Id
    实现GridView翻页并且实现CheckBox选中功能的保持
  • 原文地址:https://www.cnblogs.com/chen9510/p/7367747.html
Copyright © 2020-2023  润新知