hdu 6121(Build a tree) 瞎搞+麻烦

来源:互联网 发布:qq游戏网络异常 编辑:程序博客网 时间:2024/06/09 17:25

题目链接:点击打开链接

题目大意:给定一棵有n个结点的k叉树,求所有子树的大小的异或和~~~

多校补题日记~~~


#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;typedef long long llt;llt SIZE[100];llt L[100];//完全k叉树llt complete(llt n,int depth,int k){    if((k&1)==0) return n;    else    {        llt ans=0;        for(int i=1;i<=depth;i++)            ans^=SIZE[i];        return ans;    }}//不平衡的k叉树llt dfs(llt n,int depth,int k){    llt ret=n;    llt rem=n-SIZE[depth];    if(rem%L[depth]==0)    {        llt comp=rem/L[depth];        if(comp&1) ret^=complete(SIZE[depth],depth,k);        if((k-comp)&1) ret^=complete(SIZE[depth-1],depth-1,k);        return ret;    }    else    {        llt comp=rem/L[depth];        llt cut=rem%L[depth];        if(comp&1) ret^=complete(SIZE[depth],depth,k);        if((k-comp-1)&1) ret^=complete(SIZE[depth-1],depth-1,k);        return ret^dfs(SIZE[depth-1]+cut,depth-1,k);    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {    llt n,k;    scanf("%lld%lld",&n,&k);        if(k==1)        {            if(n%4==1) printf("%d\n",1);            else if(n%4==2) printf("%d\n",n+1);            else if(n%4==3) printf("%d\n",0);            else printf("%d\n",n);            continue;        }        int depth=1;        llt sum=1,left=k;        L[1]=1;        while(sum+left<=n)        {        SIZE[depth]=sum;        L[++depth]=left;        sum+=left;left*=k;        }        SIZE[depth]=sum;        if(sum==n) printf("%lld\n",complete(n,depth,k));        else printf("%lld\n",dfs(n,depth,k));    }    return 0;}