zoukankan      html  css  js  c++  java
  • HDU 6121 Build a tree —— 2017 Multi-University Training 7

    HazelFan wants to build a rooted tree. The tree has nn nodes labeled 0 to n−1, and the father of the node labeled i is the node labeled  . 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)T(1≤T≤5), denoting the number of test cases. 
    For each test case: 
    A single line contains two positive integers n,k(1n,k1018)n,k(1≤n,k≤1018). 
    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

    题意:画一下题目介绍的树,发现这是一个k叉树,那么题目要求所有子树大小的异或和。
    思路:我们从序号为n的节点开始,往上求异或和。n计算到某一层时,对于处在n节点左边的节点(子树),它们是t+1层的满k叉树,在右边的节点(子树)是t层的满二叉树,
    满二叉树的大小可以通过打表得到。根据异或计算的性质,大小相同的子树进行异或,有奇数个进行异或时结果为该子树的大小,偶数个时为0。
    而对n位置节点的子树来说,不是满二叉树就是非满二叉树,而且在计算这个子树大小时一旦它在某一层是非满二叉树,接下来往上它就一直是非满二叉树。
    还有,k==1时特判一下。
    具体实现参看代码。

    AC代码:
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    typedef long long LL;
    LL n, k;
    LL num[100];
    int main()
    {
        int T;
        cin>>T;
        num[0]=1;
        while(T--)
        {
            scanf("%lld %lld", &n, &k);
            if(k==1){
                if(n==1)
                    printf("%d
    ", 1);
                else if(n==2)
                    printf("%d
    ",3);
                else if(n==3)
                    printf("%d
    ", 0);
                else 
                {
                    int k=n%4;
                    if(k==0)
                        printf("%lld
    ", n);
                    else if(k==1)
                        printf("%d
    ", 1);
                    else if(k==2)
                        printf("%lld
    ", n+1);
                    else
                        printf("%d
    ", 0);
                }
                continue;
            }
            n--;
            int level=0,t=0;
            LL lm=0, rm=0;
            while(rm<n){
                t++;
                lm=rm+1;
                rm=lm*k;
                num[t]=rm+1;
            }
            LL res=0,left,right,s=n+1,m;
            t=0; 
            bool flag=0;
                LL mid=n%k;//mid判断是否为满k叉树, m为非满k叉树的大小 
                left=n-mid-lm+1;
                //cout<<left<<endl;
                if(left&1){
                    res^=num[0];
                }
                if(mid&1)
                    res^=num[0];
                if(mid)
                    flag=1;
                    
                m=(n-(n-1)/k*k)*num[0]+1;
                //cout<<m<<endl;
                while(n)
                {
                    
                    //cout<<res<<'*'<<endl;
                    
                    t++;
                    //cout<<t<<' '<<m<<endl;
                    
                    n=(n-1)/k;
                    if(n<=0)
                        break;
                    
                    mid=n%k; 
                    lm=(lm-1)/k;
                    rm=(rm-1)/k;
                    //cout<<lm<<' '<<n<<' '<<rm<<endl;
                    right=rm-n;
                    left=n-lm+1;
                    if(flag||mid){
                        flag=1;
                        left--;
                        res^=m;
                    }
                    
                    if(left&1)
                        res^=num[t];
                    if(right&1)
                        res^=num[t-1];
                    m+=(n-(n-1)/k*k-1)*num[t]+(((n-1)/k+1)*k-n)*num[t-1]+1;
                    
                }
            res^=s;
            printf("%lld
    ", res);
        }
        return 0;
    }
    
    
    


  • 相关阅读:
    【leetcode】1020. Partition Array Into Three Parts With Equal Sum
    【leetcode】572. Subtree of Another Tree
    【leetcode】123. Best Time to Buy and Sell Stock III
    【leetcode】309. Best Time to Buy and Sell Stock with Cooldown
    【leetcode】714. Best Time to Buy and Sell Stock with Transaction Fee
    【leetcode】467. Unique Substrings in Wraparound String
    【leetcode】823. Binary Trees With Factors
    【leetcode】143. Reorder List
    【leetcode】1014. Capacity To Ship Packages Within D Days
    【leetcode】1013. Pairs of Songs With Total Durations Divisible by 60
  • 原文地址:https://www.cnblogs.com/MasterSpark/p/7413163.html
Copyright © 2011-2022 走看看