大佬博客

ps:在牛客上做到这题不会,学会之后补了两道相关题。顺便记录一下。

牛客-DongDong数颜色

sol:dfs序+莫队,先把树上的点标上dfs序,因为子树的dfs序是连续的,所以子树可以表示为id[x]到id[x] + size[x] + 1,然后就是序列上莫队了(引用自官方题解)

  • dfs序 + 莫队

    1. #include "bits/stdc++.h"
    2. using namespace std;
    3. typedef pair<int, int> PII;
    4. const int MAXN = 1e5 + ;
    5. int c1[MAXN], c2[MAXN], c3[MAXN];
    6. vector<int> edge[MAXN];
    7. PII node[MAXN];
    8. int pos, size;
    9. int ans[MAXN];
    10. struct Query {
    11. int l, r;
    12. int index;
    13. } q[MAXN];
    14. void dfs(int u, int f) {
    15. c2[++pos] = c1[u];
    16. node[u].first = pos;
    17. for (int i = ; i < edge[u].size(); i++) {
    18. int v = edge[u][i];
    19. if (v == f) continue;
    20. dfs(v, u);
    21. }
    22. node[u].second = pos;
    23. }
    24. bool cmp(Query a, Query b) {
    25. if ((a.l - ) / size != (b.l - ) / size)
    26. return (a.l - ) / size < (b.l - ) / size;
    27. return a.r < b.r;
    28. }
    29. int main() {
    30. int n, m;
    31. scanf("%d%d", &n, &m);
    32. size = sqrt(n);
    33. for (int i = ; i <= n; i++)
    34. scanf("%d", &c1[i]);
    35. for (int i = ; i < n; i++) {
    36. int u, v;
    37. scanf("%d%d", &u, &v);
    38. edge[u].push_back(v);
    39. edge[v].push_back(u);
    40. }
    41. dfs(, -);
    42. for (int i = ; i <= m; i++) {
    43. int x;
    44. scanf("%d", &x);
    45. q[i].l = node[x].first;
    46. q[i].r = node[x].second;
    47. q[i].index = i;
    48. }
    49. sort (q + , q + + m, cmp);
    50. int l = , r = , k = ;
    51. for (int i = ; i <= m; i++) {
    52. while (r < q[i].r) if (++c3[c2[++r]] == ) k++;
    53. while (l > q[i].l) if (++c3[c2[--l]] == ) k++;
    54. while (r > q[i].r) if (--c3[c2[r--]] == ) k--;
    55. while (l < q[i].l) if (--c3[c2[l++]] == ) k--;
    56. ans[q[i].index] = k;
    57. }
    58. for (int i = ; i <= m; i++)
    59. printf("%d\n", ans[i]);
    60. return ;
    61. }

ps:由于我菜,官方题解上的另外两种解法没补出来,但是去网上看了其他博主的博客发现可以用树状数组代替莫队的功能,效率更高。数组数组为n*log(n),莫队为n*sqrt(n)

HDU-3333-Turing Tree

sol:离线处理,优先处理右区间在前的,不断更新每个颜色下标位置,从而在权值树状数组上统计总和;

  • 树状数组

    1. #include "bits/stdc++.h"
    2. using namespace std;
    3. typedef long long LL;
    4. const int MAXN = 1e5 + ;
    5. struct Query {
    6. int l, r;
    7. int index;
    8. } q[MAXN];
    9. int a[MAXN], pre[MAXN];
    10. LL c[MAXN], ans[MAXN];
    11. map<int, int> mp;
    12. bool cmp(Query a, Query b) {
    13. return a.r < b.r;
    14. }
    15. int lowbit(int i) {
    16. return i & (-i);
    17. }
    18. void add(int i, int k) {
    19. while (i < MAXN) {
    20. c[i] += k;
    21. i += lowbit(i);
    22. }
    23. }
    24. LL sum(int i) {
    25. LL res = ;
    26. while (i > ) {
    27. res += c[i];
    28. i -= lowbit(i);
    29. }
    30. return res;
    31. }
    32. int main() {
    33. int t, n, m;
    34. scanf("%d", &t);
    35. while (t--) {
    36. memset(c, , sizeof(c));
    37. mp.clear();
    38. scanf("%d", &n);
    39. for (int i = ; i <= n; i++)
    40. scanf("%d", &a[i]);
    41. scanf("%d", &m);
    42. for (int i = ; i <= m; i++) {
    43. scanf("%d%d", &q[i].l, &q[i].r);
    44. q[i].index = i;
    45. }
    46. sort(q + , q + + m, cmp);
    47. int r = ;
    48. for (int i = ; i <= m; i++) {
    49. while (r < q[i].r) {
    50. ++r;
    51. add(r, a[r]);
    52. if (mp.count(a[r])) add(mp[a[r]], -a[r]);
    53. mp[a[r]] = r;
    54. }
    55. ans[q[i].index] = sum(q[i].r) - sum(q[i].l - );
    56. }
    57. for (int i = ; i <= m; i++)
    58. printf("%lld\n", ans[i]);
    59. }
    60. return ;
    61. }

ps:按难易程度这题应该排在上一题上面,完全就是上一题的阉割版。上一题用莫队来写了这一题就用来练树状数组的方法了,不过这题用莫队不一定能过,这份数组数组的代码都跑了468ms,莫队可能会比较极限,没有尝试过。

CF-703D-Mishka and Interesting sum

sol:把区间所以数异或起来根据相同数字异或为0的原理得到的就是所有出现次数为奇数的数的异或值,那么联系上面两题,只要把区间内不重复出现的数都异或一遍在和区间内所有数异或一下就是我们的结果了。因为异或和加减法具有同样的一些性质也可以用树状数组来解决。

  • 树状数组+位运算

    1. #include "bits/stdc++.h"
    2. using namespace std;
    3. const int MAXN = 1e6 + ;
    4. int a[MAXN], b[MAXN], c[MAXN];
    5. map<int, int> mp;
    6. int ans[MAXN];
    7. struct Query {
    8. int l, r;
    9. int index;
    10. } q[MAXN];
    11. bool cmp(Query a, Query b) {
    12. return a.r < b.r;
    13. }
    14. int lowbit(int i) {
    15. return i & (-i);
    16. }
    17. void add(int i, int k) {
    18. while (i < MAXN) {
    19. c[i] ^= k;
    20. i += lowbit(i);
    21. }
    22. }
    23. int sum(int i) {
    24. int _xor = ;
    25. while (i > ) {
    26. _xor ^= c[i];
    27. i -= lowbit(i);
    28. }
    29. return _xor;
    30. }
    31. int main() {
    32. int n, m;
    33. scanf("%d", &n);
    34. for (int i = ; i <= n; i++) {
    35. scanf("%d", &a[i]);
    36. b[i] = a[i] ^ b[i - ];
    37. }
    38. scanf("%d", &m);
    39. for (int i = ; i <= m; i++) {
    40. scanf("%d%d", &q[i].l, &q[i].r);
    41. q[i].index = i;
    42. }
    43. sort(q + , q + + m, cmp);
    44. int r = ;
    45. for (int i = ; i <= m; i++) {
    46. while (r < q[i].r) {
    47. r++;
    48. add(r, a[r]);
    49. if (mp.count(a[r]))
    50. add(mp[a[r]], a[r]);
    51. mp[a[r]] = r;
    52. }
    53. ans[q[i].index] = (sum(q[i].r) ^ sum(q[i].l - )) ^ (b[q[i].r] ^ b[q[i].l - ]);
    54. }
    55. for (int i = ; i <= m; i++)
    56. printf("%d\n", ans[i]);
    57. return ;
    58. }

ps:这题我尝试了莫队,超时了,卡在第14组数据,莫队能过1e5的数据,这题n最大值为1e6。莫队比较好写,但还是树状数组比较快。

dfs序+莫队,先把树上的点标上dfs序,因为子树的dfs序是连续的,所以子树可以表示为id[x]到id[x]+size[x]+1id[x]到id[x]+size[x]+1,然后就是序列上莫队了

牛客-DongDong数颜色 及其相似题的更多相关文章

  1. 牛客练习赛47 E DongDong数颜色 (树上启发式合并)

    链接:https://ac.nowcoder.com/acm/contest/904/E 来源:牛客网 DongDong数颜色 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 5242 ...

  2. 牛客练习赛47 DongDong数颜色 (莫队算法)

    链接:https://ac.nowcoder.com/acm/contest/904/E 来源:牛客网 DongDong数颜色 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 5242 ...

  3. 牛客练习赛47 E DongDong数颜色 (树状数组维护区间元素种类数)

    链接:https://ac.nowcoder.com/acm/contest/904/E 来源:牛客网 DongDong数颜色 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 5242 ...

  4. 2019年牛客多校第一场B题Integration 数学

    2019年牛客多校第一场B题 Integration 题意 给出一个公式,求值 思路 明显的化简公式题,公式是分母连乘形式,这个时候要想到拆分,那如何拆分母呢,自然是裂项,此时有很多项裂项,我们不妨从 ...

  5. 【面试笔试算法】牛客网一站通Offer编程题2016.4.19

    牛客网一站通offer (一)字符串变形 1. 题目: 对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形.首先这个字符串中包含着一些空格,就像"Hello Wor ...

  6. 牛客网剑指offer刷题总结

    二维数组中的查找: 题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 两 ...

  7. 牛客G-指纹锁【一题三解】

    链接:https://www.nowcoder.com/acm/contest/136/G来源:牛客网 题目描述     HA实验有一套非常严密的安全保障体系,在HA实验基地的大门,有一个指纹锁.   ...

  8. 牛客网 牛客小白月赛1 B.简单题2-控制输出格式

    B.简单题2   链接:https://www.nowcoder.com/acm/contest/85/B来源:牛客网 和A题一样,控制输出格式就可以. 代码: 1 #include<iostr ...

  9. 牛客网 牛客小白月赛1 A.简单题-控制输出格式setiosflags()函数+setprecision()函数

    水一水博客,都不好意思写这篇博客,毕竟已经不是大一的了. 难得能把一整套题都写出来(日常智障).但是在这里不写G题あなたの蛙は旅⽴っています的题解. 有毒,G题关了流同步只能过94%的样例,说我运行超 ...

随机推荐

  1. 用python批量修改音频ID3等标签

    使用的模块是eyeD3 一.eyeD3的安装 1.安装msgpack,不安装会报错distributed 1.21.8 requires msgpack, which is not installed ...

  2. 关于 tf.image.crop_and_resize的使用

    https://blog.csdn.net/m0_38024332/article/details/81779544 关于 tf.image.crop_and_resize 的使用  最近在学习fas ...

  3. 2. 现代 javascript 新语法 及 对象专题

    let , const 和 var javascript 里面的作用域 一个大括号 是一个作用域 {  } var 会 在局部作用定义 被定义时 会提升作用域  如 if 的 {} 就属于 局部作用域 ...

  4. 树状数组--模版1和2 P3368、P3374

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 将某一个数加上 x 求出某区间每一个数的和 输入格式 第一行包含两个正整数 n,m,分别表示该数列数字的个数和操作的总个数. 第二行包含 n 个 ...

  5. FJ的字符串-简单递归

    FJ的字符串-简单递归 问题描述FJ在沙盘上写了这样一些字符串: A1 = “A” A2 = “ABA” A3 = “ABACABA” A4 = “ABACABADABACABA” … … 你能找出其 ...

  6. Ubuntu 安装软件时显示:无法获得锁 /var/lib/dpkg/lock -open(资源暂时不可用)

    出错状况:在用 sudo apt-get install 安装软件时,结果终端提示: 无法获得锁 /var/lib/dpkg/lock -open(资源暂时不可用) 无法锁定管理目录(var/lib/ ...

  7. 分组统计SQL(mysql)

    <select id="orderProductStatistics" resultMap="ProductStatisticsVOMap"> SE ...

  8. AI大火之下智能手机行业能适应这一风口吗?

    今年智能手机行业的变化,实在是让人摸不到头脑.一方面是智能手机厂商依然在拿出各种具有噱头的产品,仿佛整个市场还依然热火朝天.但在另一方面,智能手机出货量却出现大幅下滑.据中国信息通信研究院发布的数据显 ...

  9. GPIO口的脚本配置之——全志H3script.bin

    此脚本的作用之一是配置GPIO的默认状态: 如:功能,内部电阻状态,驱动能力等. 1.但是直接打开script.bin 文件则会出现乱码,那么我们怎么才可以打开并更改该脚本的配置呢? 在路径uboot ...

  10. 求Fibonacii数列的第40个数

    public class Fibonacii{ public int m1(int n){ if(n == 1||n == 2){ return 1; } return m1(n-1) + m1(n- ...