【链接】点击打开链接


【题意】


询问n个点的完全k叉树,所有子树节点个数的异或总和为多少。


【题解】


考虑如下的一棵k=3叉树,假设这棵树恰好有n个节点.

因为满的k叉树,第i层的节点个数为k^(i-1);

则我们找到最大的d;

使得

k^0+k^1+..+k^(d-1) <=n

自此,我们会发现,整棵树可以分成若干个树的深度大小d和d-1满k叉树

如上图,d=3,两个圈起来的,就是一个深度为3的满k叉树和一个深度为2的满k叉树

当然,还可能会有一个子树,它不是满的k叉树

如上图中没有被圈出来的部分.

深度大小为d的满k叉树的个数,可以用rest =
n-(k^0+k^1+..+k^(d-1))算出来;

它的个数就是rest/num[d],(其中num[d]表示第d层的满k叉树的节点个数.)

就是每num[d]个最下边的那些点可以将一个深度为d-1的满k叉树组成深度为d的满k叉树

然后看看rest%num[d]是不是为0.

如果不为0的话,就会有一棵子树不是满k叉树;

则肯定还有k-rest/num[d]-1棵是深度为d-1的满k叉树

然后思考那个不是满k叉树的

会发现.那棵子树的问题。仍然是我们最开始面临的问题

可以递归解决的!

获取那个子树的大小,然后递归解决就好!

(深度为d和深度为d-1的满k叉树的子树异或和,单独写一个dfs来做就好)

(不要忘记有多个子树,所以对应的答案要异或和子树的个数对应次数)

k=1的情况要单独处理。找规律就好。就是1^2^3..^n的值。。

(要注意根节点的儿子不够k个的情况。。那个时候就不用递归了,直接处理答案)


【错的次数】


0

【反思】



编程比较难。思路不难想。

【代码】

#include <bits/stdc++.h>
using namespace std;
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define ri(x) scanf("%d",&x)
#define rl(x) scanf("%lld",&x)
#define oi(x) printf("%d",x)
#define ol(x) printf("%lld",x)
#define os(x) printf(x)
#define LL long long LL k,num[100],tot[100],ans; LL f(LL x,LL y){
    if (y&1)
        return x;
    else
        return 0;
} LL dfs(int d){
    LL now = 0,temp = 0;
    rep2(i,d,1){
        temp = temp*k + 1;
        now ^= f(temp,num[i]);
    }
    return now;
} void solve(LL n){
    num[1] = 1,tot[1] = 1;
    int d = 1;
    while (1){
        d++;
        num[d] = num[d-1]*k;
        tot[d] = tot[d-1]+num[d];
        if (tot[d]>n) break;
    }
    d--;
    LL numdp1 = 0,numd = 0,rest = n-tot[d];
    if (d == 1 && rest <= k){
        ans ^= f(1,rest);
        ans ^= n;
        return;
    }
    numdp1 = rest/num[d],numd = k - numdp1 - 1;
    LL trest = rest%num[d];     ans ^= f(dfs(d),numdp1);     LL temp1 = dfs(d-1);
    ans ^= f(temp1,numd);     if (trest==0)
        ans ^= temp1;
     else
        solve(trest+tot[d-1]);     ans ^= n;
} int main(){
    //freopen("D:\\rush.txt","r",stdin);
    int T;
    ri(T);
    while (T--){
        LL n;
        rl(n),rl(k);
        ans = 0;
        if (k==1){
            n--;
            if (n%4==0) ans = 1;
            if (n%4==1) ans = n + 2;
            if (n%4==2) ans = 0;
            if (n%4==3) ans = n+1;
        }else
            solve(n);
        ol(ans);puts("");
    }
    return 0;
}

【2017 Multi-University Training Contest - Team 7 && hdu 6121】Build a tree的更多相关文章

  1. 【 2017 Multi-University Training Contest - Team 9 && hdu 6162】Ch’s gift

    [链接]h在这里写链接 [题意] 给你一棵树,每个节点上都有一个权值. 然后给你m个询问,每个询问(x,y,a,b); 表示询问x->y这条路径上权值在[a,b]范围内的节点的权值和. [题解] ...

  2. 2017 Multi-University Training Contest - Team 2 &&hdu 6050 Funny Function

    Funny Function Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. 2017 Multi-University Training Contest - Team 2 &&hdu 6053 TrickGCD

    TrickGCD Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  4. 2017 Multi-University Training Contest - Team 2&&hdu 6047 Maximum Sequence

    Maximum Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. 2017 Multi-University Training Contest - Team 2 &hdu 6055 Regular polygon

    Regular polygon Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  6. 【2017中国大学生程序设计竞赛 - 网络选拔赛 && hdu 6154】CaoHaha's staff

    [链接]点击打开链接 [题意] 给你一个面积,让你求围成这个面积最少需要几条边,其中边的连线只能是在坐标轴上边长为1的的线或者是两个边长为1 的线的对角线. [题解] 找规律题 考虑s[i]表示i条边 ...

  7. 【2017中国大学生程序设计竞赛 - 网络选拔赛 hdu 6150】Vertex Cover

    [链接]点击打开链接 [题意] 有人写了一个最小点覆盖的贪心算法,然后,让你去hack它. 并且,要求这个算法得到的错误答案,是正确答案的三倍. 让你任意输出hack数据,点数<=500 [题解 ...

  8. 2017 Multi-University Training Contest - Team 1 1006&&HDU 6038 Function【DFS+数论】

    Function Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  9. 2017 Multi-University Training Contest - Team 9 1005&&HDU 6165 FFF at Valentine【强联通缩点+拓扑排序】

    FFF at Valentine Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

随机推荐

  1. Vue中对data的操作

    1. {{a}} var vm = new Vue({ el: '#app', data: { a: { a: 1, b: 2 } } })   vm.a.c = 'sadoisad' // 按理说是 ...

  2. 学习《人人都是产品经理2.0:写给泛产品经理》高清中文PDF+苏杰(作者)

    <人人都是产品经理2.0--写给泛产品经理>将从人开始,以人结束,中间说事,以一个产品从无到有的过程为框架--想清楚.做出来.推出去,外加一章综合案例.其中,最重要的想清楚.做出来.推出去 ...

  3. 记一次 CORS 跨域请求出现 OPTIONS 请求的问题及解决方法

    今天前后端在联调接口的时候,发生了跨域请求资源获取不到的问题. 首先说明下跨域问题的由来.引自HTTP 访问控制 的一段话: 当 Web 资源请求由其它域名或端口提供的资源时,会发起跨域 HTTP 请 ...

  4. Windows 操作系统与 .NET Framework

    Windos 2000 在单位的机房里好不easy才找到一台安装 Windows 2000 Server SP4 操作系统的server.这台硕果仅存的server到本月底也要退役了. Windows ...

  5. UNIX多线程编程

    一个程序至少有一个进程.一个进程至少有一个线程.进程拥有自己独立的存储空间,而线程能够看作是轻量级的进程,共享进程内的全部资源.能够把进程看作一个工厂.线程看作工厂内的各个车间,每一个车间共享整个工厂 ...

  6. js---08函数 定时器

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  7. The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified.

    https://stackoverflow.com/questions/30045871/sorting-the-view-based-on-frequency-in-sql-server Just ...

  8. .Net接口调试与案例

    1.通过查看日志,可以看出问题的原因. 2.断点调试. 3.本地测试,确保无误后,线上测试. 4.输出测试. 通过get的方式,测试接口. // [HttpPost] public ActionRes ...

  9. split---将文件分割成多个小文件

    split命令可以将一个大文件分割成很多个小文件,有时需要将文件分割成更小的片段,比如为提高可读性,生成日志等. 选项 -b:值为每一输出档案的大小,单位为 byte. -C:每一输出档中,单行的最大 ...

  10. read---读取变量值

    read命令从键盘读取变量的值,通常用在shell脚本中与用户进行交互的场合.该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开.在read命令后面,如果没有指定变量名,读取的数据将被自 ...