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

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. 第一次实战:XX漫画的XSS盲打

    第一次实战:XX漫画的XSS盲打 XSS盲打 盲打是一种惯称的说法,就是不知道有没有XSS漏洞存在的情况下,不顾一切的输入XSS代码在留言啊投诉窗口啊之类的地方,尽可能多的尝试XSS的语句,就叫盲打. ...

  2. golang sqlx

    在项目中我们通常可能会使用database/sql连接MySQL数据库.本文借助使用sqlx实现批量插入数据的例子,介绍了sqlx中可能被你忽视了的sqlx.In和DB.NamedExec方法. sq ...

  3. vue + WangEnduit

    components 注册组件 <template lang="html"> <div class="editor"> <div ...

  4. OAuth2-简介

    1. 简介 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用.因此OAUTH是安全的. ...

  5. shell循环之跳出循环

    1.break break命令允许跳出所有循环(终止执行后面的所有循环). 下面的例子中,脚本进入死循环直至用户输入数字大于5.要跳出这个循环,返回到shell提示符下,需要使用break命令. #! ...

  6. noip模拟47

    原版在 \(linux\) 本地写完没保存关机给没了-- 再简单写一下 \(t2\) 用 \(dp\) 转移 \(f[i]=\sum _ {j=last[a[i]]}^{i-1} f[j]\) 用前缀 ...

  7. ASP.NET Core Web API 教程 - Project Configuration

    ASP.NET Core Web API 教程 本系列文章主要参考了<Ultimate ASP.NET Core 3 Web API>一书,我对原文进行了翻译,同时适当删减.修改了一部分内 ...

  8. wpf 多表头

    WPF多表头技术探索总结 方案一:Grid+TextBlock嵌套DataGrid方式. 该方案是现在项目中已使用的方案.实现起来比较简单,但不具有通用性,不同数据DataGrid需要指定不同的Tex ...

  9. pip安装更换国内源

    镜像地址:阿里云 https://mirrors.aliyun.com/pypi/simple/豆瓣http://pypi.douban.com/simple/清华大学 https://pypi.tu ...

  10. 如何写出安全又可靠的PHP脚本

    前言 咔咔目前所做的项目是一个saas系统,在开发新功能之后,需要为用户角色添加相应的权限,这时整个系统的所有用户都需要添加相应的权限. 因为以前系统的缺陷现在只能用脚本来处理这些工作,所以接下来咔咔 ...