(嘤嘤嘤 又是一个自闭了一晚上的题)

qwq果然不是平面上的点的问题,也可以直接用KDTree打暴力

我们对于巧克力直接建kdtree

维护一个\(mx[i],mn[i]\)

但是有一个非常不友好的事情

我们貌似很难对这个东西进行一些实质上的剪枝

因为他求的是一个和的形式,而不是一个最值QWQ

那么该怎么办呢?

我们这时候考虑,对于一个kdtree上的每一个节点,我们都维护一个子树sum表示子树内的所有巧克力的权值之和。

那么对于一次\(query\),假设我们最大的甜度都不会超过\(c\)的话,那就代表我们可以直接把这个子树的\(sum\)加进\(ans\)里面了,因为他是一定能合法的

  1. int getsum(cho a,peo b)
  2. {
  3. if (!a.num) return 1e9;
  4. int tmp =0;
  5. for (int i=0;i<=1;i++)
  6. tmp=tmp+a.d[i]*b.d[i];
  7. return tmp;
  8. }
  9. int calc(cho a,peo b)
  10. {
  11. if (!a.num) return 1e9;
  12. int tmp =0;
  13. for (int i=0;i<=1;i++)
  14. tmp=tmp+min(a.mn[i]*b.d[i],a.mx[i]*b.d[i]);
  15. return tmp;
  16. }
  17. int getmax(cho a,peo b)
  18. {
  19. if (!a.num) return 1e9;
  20. int tmp = 0;
  21. for (int i=0;i<=1;i++)
  22. tmp=tmp+max(a.mx[i]*b.d[i],a.mn[i]*b.d[i]);
  23. return tmp;
  24. }
  25. void query(int x)
  26. {
  27. if (!x) return;
  28. if (getmax(t[x],now)<now.c)
  29. {
  30. tmp=tmp+t[x].sum;
  31. return;
  32. }
  33. int c = now.c;
  34. int d1 = calc(t[t[x].l],now);
  35. int d2 = calc(t[t[x].r],now);
  36. int d = getsum(t[x],now);
  37. if (d<now.c) tmp=tmp+t[x].val;
  38. if (d1<c) query(t[x].l);
  39. if (d2<c) query(t[x].r);
  40. }

那么其实剩下的问题也就迎刃而解了

直接上代码吧

  1. // luogu-judger-enable-o2
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<algorithm>
  5. #include<cstring>
  6. #include<cmath>
  7. #include<queue>
  8. #include<map>
  9. #include<set>
  10. #define mk makr_pair
  11. #define ll long long
  12. #define int long long
  13. using namespace std;
  14. inline int read()
  15. {
  16. int x=0,f=1;char ch=getchar();
  17. while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  18. while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  19. return x*f;
  20. }
  21. const int maxn = 3e6+1e2;
  22. struct cho{
  23. int mn[2],mx[2];
  24. int d[2];
  25. int l,r;
  26. int val;
  27. int sum;
  28. int num;
  29. };
  30. struct peo{
  31. int d[2],c;
  32. };
  33. cho t[maxn];
  34. peo now;
  35. int n,m,root;
  36. int sum;
  37. int ymh;
  38. int tmp;
  39. bool operator < (cho a,cho b)
  40. {
  41. return a.d[ymh]<b.d[ymh];
  42. }
  43. void up(int root)
  44. {
  45. for (int i=0;i<=1;i++)
  46. {
  47. if (t[root].l)
  48. {
  49. t[root].mn[i]=min(t[root].mn[i],t[t[root].l].mn[i]);
  50. t[root].mx[i]=max(t[root].mx[i],t[t[root].l].mx[i]);
  51. }
  52. if (t[root].r)
  53. {
  54. t[root].mn[i]=min(t[root].mn[i],t[t[root].r].mn[i]);
  55. t[root].mx[i]=max(t[root].mx[i],t[t[root].r].mx[i]);
  56. }
  57. }
  58. t[root].sum=t[root].val+t[t[root].l].sum+t[t[root].r].sum;
  59. }
  60. void build(int &x,int l,int r,int dd)
  61. {
  62. //cout<<1<<endl;
  63. ymh = dd;
  64. int mid = l+r >> 1;
  65. x = mid;
  66. nth_element(t+l,t+x,t+r+1);
  67. for (int i=0;i<=1;i++) t[x].mn[i]=t[x].mx[i]=t[x].d[i];
  68. if (l<x) build(t[x].l,l,mid-1,dd^1);
  69. if (r>x) build(t[x].r,mid+1,r,dd^1);
  70. up(x);
  71. }
  72. int getsum(cho a,peo b)
  73. {
  74. if (!a.num) return 1e9;
  75. int tmp =0;
  76. for (int i=0;i<=1;i++)
  77. tmp=tmp+a.d[i]*b.d[i];
  78. return tmp;
  79. }
  80. int calc(cho a,peo b)
  81. {
  82. if (!a.num) return 1e9;
  83. int tmp =0;
  84. for (int i=0;i<=1;i++)
  85. tmp=tmp+min(a.mn[i]*b.d[i],a.mx[i]*b.d[i]);
  86. return tmp;
  87. }
  88. int getmax(cho a,peo b)
  89. {
  90. if (!a.num) return 1e9;
  91. int tmp = 0;
  92. for (int i=0;i<=1;i++)
  93. tmp=tmp+max(a.mx[i]*b.d[i],a.mn[i]*b.d[i]);
  94. return tmp;
  95. }
  96. void query(int x)
  97. {
  98. if (!x) return;
  99. if (getmax(t[x],now)<now.c)
  100. {
  101. tmp=tmp+t[x].sum;
  102. return;
  103. }
  104. int c = now.c;
  105. int d1 = calc(t[t[x].l],now);
  106. int d2 = calc(t[t[x].r],now);
  107. int d = getsum(t[x],now);
  108. if (d<now.c) tmp=tmp+t[x].val;
  109. if (d1<c) query(t[x].l);
  110. if (d2<c) query(t[x].r);
  111. }
  112. signed main()
  113. {
  114. //freopen("a.in","r",stdin);
  115. //freopen("a.out","w",stdout);
  116. n=read(),m=read();
  117. for (int i=1;i<=n;i++)
  118. {
  119. for(int j=0;j<=1;j++) t[i].d[j]=read();
  120. t[i].val=read();
  121. t[i].num=i;
  122. }
  123. build(root,1,n,0);
  124. for(int i=1;i<=m;i++){
  125. now.d[0]=read();
  126. now.d[1]=read();
  127. now.c=read();
  128. tmp=0;
  129. query(root);
  130. cout<<tmp<<"\n";
  131. }
  132. return 0;
  133. }

不过总的来说

kdtree真的是一个很优雅的暴力啊!

嘤嘤嘤

洛谷4475 巧克力王国(KD-Tree + 维护子树和)的更多相关文章

  1. 洛谷P4475 巧克力王国

    洛谷P4475 巧克力王国 题目描述 巧克力王国里的巧克力都是由牛奶和可可做成的. 但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜欢过于甜的巧克力. 对于每一块巧克力,我们设 x 和 y 为 ...

  2. 洛谷 P4475 巧克力王国 解题报告

    P4475 巧克力王国 题目描述 巧克力王国里的巧克力都是由牛奶和可可做成的.但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜欢过于甜的巧克力. 对于每一块巧克力,我们设 \(x\) 和 \( ...

  3. P4475 巧克力王国 k-d tree

    思路:\(k-d\ tree\) 提交:2次 错因:\(query\)时有一个\(mx\)误写成\(mn\)窝太菜了. 题解: 先把\(k-d\ tree\)建出来,然后查询时判一下整个矩形是否整体\ ...

  4. 洛谷P3018 [USACO11MAR]树装饰Tree Decoration

    洛谷P3018 [USACO11MAR]树装饰Tree Decoration树形DP 因为要求最小,我们就贪心地用每个子树中的最小cost来支付就行了 #include <bits/stdc++ ...

  5. 【洛谷1501】[国家集训队] Tree II(LCT维护懒惰标记)

    点此看题面 大致题意: 有一棵初始边权全为\(1\)的树,四种操作:将两点间路径边权都加上一个数,删一条边.加一条新边,将两点间路径边权都加上一个数,询问两点间路径权值和. 序列版 这道题有一个序列版 ...

  6. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  7. 洛谷P2633 Count on a tree(主席树上树)

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

  8. 洛谷P2633 Count on a tree(主席树,倍增LCA)

    洛谷题目传送门 题目大意 就是给你一棵树,每个点都有点权,每次任意询问两点间路径上点权第k小的值(强制在线). 思路分析 第k小......又是主席树了.但这次变成树了,无法直接维护前缀和. 又是树上 ...

  9. 洛谷P2633 Count on a tree(主席树,倍增LCA,树上差分)

    洛谷题目传送门 题目大意 就是给你一棵树,每个点都有点权,每次任意询问两点间路径上点权第k小的值(强制在线). 思路分析 第k小......又是主席树了.但这次变成树了,无法直接维护前缀和. 又是树上 ...

随机推荐

  1. tensorflow models flags 初步使用

    参考官方仓库:https://github.com/tensorflow/models/tree/master/official/utils/flags 测试Demo代码如下: from absl i ...

  2. 前缀和的n个神奇操作

    前情回顾 前缀和的基础用法戳这里->传送门 众所周知,简单的前缀和解决的一般都是静态查询的问题,例如区间和.区间积等 操作的时候也很简单,就是根据需要来维护一个数组,每次查询的时候就用到tr[r ...

  3. vue 引用省市区三级联动(element-ui select)

    npm 下载 axios npm install --save axios static 静态文件夹里 创建 json 文件夹 json 文件夹里创建 map.json map.json 文件里写 ( ...

  4. (二)羽夏看C语言——容器

    写在前面   由于此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇 ...

  5. SSH整合(二)

    SSH框架实现登录.新闻增删改查.树形菜单 项目结构 pom.xml 网不好不要一次引入太多,容易下不全 <project xmlns="http://maven.apache.org ...

  6. JS014. toFixed( )调试踩坑 - 浏览器思维 点常量 & 点运算符

    Number.prototype.toFixed( ) 在观察toFixed()丢失精度问题,和对toFixed()方法重写的调试过程时,发现toFixed()对Number的识别有它自己的规则,并找 ...

  7. java线程day-01

    综述:下面写的是我学习java线程时做的一些笔记和查阅的一些资料总结而成.大多以问答的形式出现. 一.什么是线程? 答:线程是一个轻量级的进程,现在操作系统中一个基本的调度单位,而且线程是彼此独立执行 ...

  8. Docker系列(20)- 数据卷容器

    数据卷容器 什么是数据卷容器? 容器和容器之间实现数据共享 一个容器先于宿主机创建挂载方式,宿主机就会有改卷的目录 第二个容器使用命令--volumes-from 第一个容器,共享使用了第一个容器与宿 ...

  9. JavaScript进阶面向对象ES6

    类和对象 对象:万物皆对象,对象是一个具体的事物,看得见摸得着的实物 对象是由属性和方法组成的: 属性:事物的特征,再对象中用属性来表示(常用名词) 方法:事物的行为,再对象中用方法来表示(常用动词) ...

  10. python json格式化打印

    编写python脚本,调试的时候需要打印json格式报文,直接打印看不出层次,可以使用json.dumps格式化打印 import json import requests def test_json ...