hdu 6121 Build a tree (模拟)

来源:互联网 发布:网络教师招聘兼职 编辑:程序博客网 时间:2024/06/15 17:26

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

一个模拟。。很多因素导致比赛的时候没有写出来。。

改了改发现自己写着的时候想叉了,用一个递归记录最后一层的数量 那么从下往上回溯记录层数,那么最后一层对上面每一层棵树的影响是 re/(k^h) h是从下往上的层数,我从次底层开始回溯,分成三部分求和,第一部分是左边受到最后一层是满的的影响,第二部分是有余数的话对这一棵的影响,第三部分是右边没有受到最下面一层的影响

这里还有一个知识点:
求1异或到n

#include <iostream>  using namespace std;  unsigned xor_n(unsigned n)  {      unsigned t = n & 3;      if (t & 1) return t / 2u ^ 1;      return t / 2u ^ n;  }  int main(int argc, char* argv[])  {     const int N = 12;      cout<<xor_n(12)<<endl;      int n = 1,sum=0;      while (n<N+1)      {        sum = sum^n;        n++;      }      cout<<sum<<endl;      return 0;   }  

真正的代码

#include <bits/stdc++.h>using namespace std;typedef long long ll;ll n,k;ll h;ll ans;ll ss[110];ll qpow(ll a,ll b){    ll res=1;    while(b)    {        if(b&1) res=res*a;        a*=a;        b>>=1;    }    return res;}ll dfs(ll sum,ll dep,ll k){    ss[dep]=sum;    if(sum+qpow(k,dep+1)>=n)    {        ll res=n-sum;        ans^=(res%2);        ll hh=res;        h++;        ll beishu=qpow(k,h);        ll no=hh/beishu;        ll yu=hh%beishu;        ll zong=qpow(k,dep);        if(yu){            zong=zong-no-1;            ll summ=0;            summ=(zong%2)*(ss[h-1]);            ans^=summ;            ll sum1=(no%2)*(ss[h]);            ans^=sum1;            ll sum3=0;            sum3=(ss[h-1])+res%beishu;            ans^=sum3;        }        else        {            zong=zong-no;            ll summ=0;            summ=(zong%2)*(ss[h-1]);            ans^=summ;            ll sum1=(no%2)*(ss[h]);            ans^=sum1;        }    return res;    }    ll res=dfs(sum+qpow(k,dep+1),dep+1,k);    ll hh=res;    h++;    ll bei=qpow(k,h);//就是它下面管辖和它自身的子树点数    ll no1=hh/bei;    ll yu1=hh%bei;    ll zong1=qpow(k,dep);    if(yu1){        zong1=zong1-no1-1;        ll summ1=0;        summ1=(zong1%2)*(ss[h-1]);        ans^=summ1;        ll sum11=(no1%2)*(ss[h]);        ans^=sum11;        ll sum33=0;        sum33=(ss[h-1])+res%bei;        ans^=sum33;    }    else    {        zong1=zong1-no1;        ll summ1=0;        summ1=(zong1%2)*(ss[h-1]);        ans^=summ1;        ll sum11=(no1%2)*(ss[h]);        ans^=sum11;    }    return res;}ll xor_n(ll n){    ll tt = n&3;    if(tt&1) return tt/2ll^1;    return tt/2ll^n;}int main(){    int t;    scanf("%d",&t);    while(t--){        ans=0;        h=0;        scanf("%lld%lld",&n,&k);        if(k==1)        {         printf("%lld\n",xor_n(n));        continue;        }        dfs(1,0,k);        printf("%lld\n",ans);    }}
原创粉丝点击