HDU6121-Build a tree

来源:互联网 发布:淘宝返现哪个最好用 编辑:程序博客网 时间:2024/05/16 18:47

Build a tree

                                                                         Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
                                                                                                   Total Submission(s): 609    Accepted Submission(s): 206


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
25 25 3
 

Sample Output
76
 

Source
2017 Multi-University Training Contest - Team 7
 

题意:有一棵树,第i个点的父亲节点为i1k⌋,求出所有子树大小的异或值

解题思路:可以明显发现这是一棵k叉完全树,最多只有一个不是满k叉树,那么只要对这个孩子就是递归即可,1的情况需要特判


#include <iostream>#include <cstdio>#include <cstring>#include <map>#include <set>#include <string>#include <cmath>#include <algorithm>#include <vector>#include <bitset>#include <stack>#include <queue>#include <unordered_map>#include <functional>using namespace std;const int INF=0x3f3f3f3f;#define LL long longLL n,k,ans;void dfs(LL x){    ans^=x;    x--;    LL p=1,xx=x,ans1=0,ans2=0,pp,sum=0,g=1;    while(xx>=p*k) {xx-=p*k,p*=k;}    pp=p/k;    while(pp)    {        sum+=g;        if(pp&1) ans1^=sum;        pp/=k;        g*=k;    }    if(xx%p) dfs(sum+xx%p);    sum=0,g=1,pp=p;    while(p)    {        sum+=g;        if(p&1) ans2^=sum;        p/=k;        g*=k;    }    LL cnt2=xx/pp;    LL cnt1=k-cnt2-(xx%pp?1:0);    if(cnt2&1) ans^=ans2;    if(cnt1&1) ans^=ans1;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%lld%lld",&n,&k);        if(k==1)        {            if(n%4==0) printf("%lld\n",n);            else if(n%4==1) printf("1\n");            else if(n%4==2) printf("%lld\n",n+1LL);            else printf("0\n");            continue;        }        ans=0;        dfs(n);        printf("%lld\n",ans);    }    return 0;}

原创粉丝点击