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

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

我们对于巧克力直接建kdtree

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

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

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

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

那么该怎么办呢?

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

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

int getsum(cho a,peo b)
{
if (!a.num) return 1e9;
int tmp =0;
for (int i=0;i<=1;i++)
tmp=tmp+a.d[i]*b.d[i];
return tmp;
}
int calc(cho a,peo b)
{
if (!a.num) return 1e9;
int tmp =0;
for (int i=0;i<=1;i++)
tmp=tmp+min(a.mn[i]*b.d[i],a.mx[i]*b.d[i]);
return tmp;
}
int getmax(cho a,peo b)
{
if (!a.num) return 1e9;
int tmp = 0;
for (int i=0;i<=1;i++)
tmp=tmp+max(a.mx[i]*b.d[i],a.mn[i]*b.d[i]);
return tmp;
}
void query(int x)
{
if (!x) return;
if (getmax(t[x],now)<now.c)
{
tmp=tmp+t[x].sum;
return;
}
int c = now.c;
int d1 = calc(t[t[x].l],now);
int d2 = calc(t[t[x].r],now);
int d = getsum(t[x],now);
if (d<now.c) tmp=tmp+t[x].val;
if (d1<c) query(t[x].l);
if (d2<c) query(t[x].r);
}

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

直接上代码吧

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk makr_pair
#define ll long long
#define int long long using namespace std; inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
} const int maxn = 3e6+1e2; struct cho{
int mn[2],mx[2];
int d[2];
int l,r;
int val;
int sum;
int num;
}; struct peo{
int d[2],c;
}; cho t[maxn];
peo now;
int n,m,root;
int sum;
int ymh;
int tmp; bool operator < (cho a,cho b)
{
return a.d[ymh]<b.d[ymh];
} void up(int root)
{
for (int i=0;i<=1;i++)
{
if (t[root].l)
{
t[root].mn[i]=min(t[root].mn[i],t[t[root].l].mn[i]);
t[root].mx[i]=max(t[root].mx[i],t[t[root].l].mx[i]);
}
if (t[root].r)
{
t[root].mn[i]=min(t[root].mn[i],t[t[root].r].mn[i]);
t[root].mx[i]=max(t[root].mx[i],t[t[root].r].mx[i]);
}
}
t[root].sum=t[root].val+t[t[root].l].sum+t[t[root].r].sum;
} void build(int &x,int l,int r,int dd)
{
//cout<<1<<endl;
ymh = dd;
int mid = l+r >> 1;
x = mid;
nth_element(t+l,t+x,t+r+1);
for (int i=0;i<=1;i++) t[x].mn[i]=t[x].mx[i]=t[x].d[i];
if (l<x) build(t[x].l,l,mid-1,dd^1);
if (r>x) build(t[x].r,mid+1,r,dd^1);
up(x);
} int getsum(cho a,peo b)
{
if (!a.num) return 1e9;
int tmp =0;
for (int i=0;i<=1;i++)
tmp=tmp+a.d[i]*b.d[i];
return tmp;
}
int calc(cho a,peo b)
{
if (!a.num) return 1e9;
int tmp =0;
for (int i=0;i<=1;i++)
tmp=tmp+min(a.mn[i]*b.d[i],a.mx[i]*b.d[i]);
return tmp;
}
int getmax(cho a,peo b)
{
if (!a.num) return 1e9;
int tmp = 0;
for (int i=0;i<=1;i++)
tmp=tmp+max(a.mx[i]*b.d[i],a.mn[i]*b.d[i]);
return tmp;
}
void query(int x)
{
if (!x) return;
if (getmax(t[x],now)<now.c)
{
tmp=tmp+t[x].sum;
return;
}
int c = now.c;
int d1 = calc(t[t[x].l],now);
int d2 = calc(t[t[x].r],now);
int d = getsum(t[x],now);
if (d<now.c) tmp=tmp+t[x].val;
if (d1<c) query(t[x].l);
if (d2<c) query(t[x].r);
} signed main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout); n=read(),m=read();
for (int i=1;i<=n;i++)
{
for(int j=0;j<=1;j++) t[i].d[j]=read();
t[i].val=read();
t[i].num=i;
}
build(root,1,n,0);
for(int i=1;i<=m;i++){
now.d[0]=read();
now.d[1]=read();
now.c=read();
tmp=0;
query(root);
cout<<tmp<<"\n";
}
return 0;
}

不过总的来说

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. canvas——动画实例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. springboot系列总结(二)---springboot的常用注解

    上一篇文章我们简单讲了一下@SpringBootApplication这个注解,申明让spring boot自动给程序进行必要的配置,他是一个组合注解,包含了@ComponentScan.@Confi ...

  3. centos7系统上pgsql的一些报错解决方法

    1.2021-07-15 # 问题: 登录时服务器拒绝连接 psql -h 192.168.1.112 # 解决方法:修改配置文件 pg_hba.conf ,将该主机加进白名单 vi pg_hba.c ...

  4. SSL基础知识及Nginx/Tomcat配置SSL

    HTTPS 是在 HTTPS 基础之上添加 SSL/TLS 使网络通讯加密,进而确保通信安全.可简记为 HTTPS = HTTP + SSL/TLS 本文档主要讲解常规SSL格式.Nginx 与 To ...

  5. React Native startReactApplication 方法简析

    在 React Native 启动流程简析 这篇文章里,我们梳理了 RN 的启动流程,最后的 startReactApplication 由于相对复杂且涉及到最终执行前端 js 的流程,我们单独将其提 ...

  6. DorisDB升级为StarRocks,全面开源!

    今天被朋友圈刷屏了,StarRocks开源--携手未来,星辰大海! 原文链接:StarRocks开源--携手未来,星辰大海! 可能大家对StarRocks不太熟悉,但是DorisDB想必都是听说过的. ...

  7. shell脚本书写

    #!/bin/bash #指定脚本默认使用的命令解释器 第1行 幻数 #!/usr/bin/python #!/bin/awk #!/bin/sed

  8. fetch ios低版本兼容cannot clone a disturbed response

    报错信息 ios 11以下 cannot clone a disturbed response github.com/github/fetc- 问题发生场景 使用了一个或者多个三方库 三方库或者自己的 ...

  9. windows 安装pip 及更换pip国内源

    一.官网下载压缩包并解压. 官网:https://pypi.org/project/pip/#files 文件:选择.tar.gz版本 image 解压后,进入解压文件目录,在当前路径下打开cmd窗口 ...

  10. Identity用户管理入门六(判断是否登录)

    目前用户管理的增删改查及登录功能已经全部实现,但存在一个问题,登录后要取消登录按钮显示退出按钮,未登录应该有注册按钮,现实现过程如下 一.Startup.cs中增加服务 app.UseAuthenti ...