尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

做题随笔:P14521

做题随笔:P14521
📅 发布时间:2026/6/19 22:17:07

Solution

题意

原题链接

感觉题意很难形式化,建议自己读一下。

大概是:给一个定根树,每个点有一个点权,每条边有一个可通过区间,从根开始,带着一个初值向下走,每到一个点把点权加在值上,对初值 \(x\) 的 \(q\) 个取值求可达点数量。

注意:根节点算可达点,根节点的点权也要加上。

分析

首先有一个很自然的思路:对于一个可达点 \(u\),如果初值是 \(x\),从根到 \(u\) 的路径点权和是 \(s\),到达 \(u\) 时的值就是 \(x+s\)。于是对于 \(u\) 向下的边,如果它的可通过区间是 \([l,r]\),那么可以通过这条边的初值区间就是 \([l-s,r-s]\)。

好的,其实就做完了。我们直接 dfs 一次计算根到所有点的路径点权,并计算可通过区间。注意一下每个点的可达区间应对父亲取交,毕竟要先到父亲才能到它。至于统计答案,我们需要做区间加,单点查,写个差分数组就完……了吗?

注意到 \(x \in [-1 \times 10^{18},1 \times 10^{18}]\),差分数组完全开不下。但是,我们发现:每个树上的点会做两次差分数组上的操作,所以只有 \(O(n)\) 个差分数组的位是有意义的,那我们只对这些位操作就行了。相当于是:我们“离散化”了差分数组。

具体地,开一个 vector,存 \(x,d\) 表示我需要在差分数组的 \(x\) 位上执行加 \(d\) 操作。查询离线一下,对 \(x\) 排序后扫,就扫完 \(x\) 及之前的求和就行(这好像叫扫描线是吧)。

Tip:注意要扔掉 \(l>r\) 的区间,不然差分数组会错。赛时蒟蒻就是这样调了 30min。

注意下路径点权和会爆 long long,记得开 int128。

Code

#include <iostream>
#include <cctype>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <climits>typedef long long ll;ll fr() {ll x=0,f=1;char c=getchar();while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+(c^48);c=getchar();}return x*f;
}struct node{ll i;int d;bool operator< (const node &n) const&{return i<n.i;}
};std::vector<node> v;//差分数组的 vectorconst int maxn=5e5+100;struct edge{int v,nxt;ll l,r;
}e[maxn<<1];int head[maxn],tot;void ade(int u,int v,ll l,ll r) {e[++tot]={v,head[u],l,r};head[u]=tot;
}ll a[maxn];void dfs(int u,__int128_t dx,ll fl,ll fr) {dx+=a[u];for(int i = head[u]; i; i=e[i].nxt) {__int128_t l=e[i].l,r=e[i].r;l+=dx,r+=dx;l=std::max((__int128_t)-1e18-100,l),r=std::min((__int128_t)1e18+100,r);//x 的范围只有这么大,多的不用管l=std::max((ll)l,fl),r=std::min((ll)r,fr);if(l>r) continue;v.push_back({(ll)l,1});v.push_back({(ll)r+1,-1});dfs(e[i].v,dx,l,r);}
}struct qry{ll x;int id,ans;
};bool cmp1(qry q1,qry q2) {return q1.x<q2.x;
}bool cmp2(qry q1,qry q2) {return q1.id<q2.id;
}qry Q[maxn<<1];int main() {int n=fr(),q=fr();v.reserve(n<<1);for(int i = 1; i < n; i++) {int p=fr();ll l=fr(),r=fr();ade(p,i+1,l,r);}for(int i = 1; i <= n; i++) a[i]=-fr();dfs(1,0,LLONG_MIN,LLONG_MAX);std::sort(v.begin(),v.end());for(int i = 1; i <= q; i++) Q[i]={fr(),i,0};std::sort(Q+1,Q+1+q,cmp1);int now=0;int p=0;for(int i = 1; i <= q; i++) {ll x=Q[i].x;while(p<v.size()&&v[p].i<=x) {now+=v[p].d;p++;}Q[i].ans=now;}std::sort(Q+1,Q+1+q,cmp2);for(int i = 1; i <= q; i++) printf("%d\n",Q[i].ans+1);return 0;
}

一些闲话

如果觉得有用,点个赞吧!

相关新闻

  • Win11系统恢复经典的右键菜单方法(CMD快速执行)
  • 20251116
  • 选拔赛题解

最新新闻

  • 3种智能编排策略重构AI工作流创作效率
  • PPO算法在大语言模型RLHF训练中的工程实践与调参指南
  • 武汉南华光电职业技术学校2026年最新招生简章 - 武汉中职最新信息发布
  • 2026年电大中专/成人中专招生简章(可考消防员和造价工程师) - 武汉中职最新信息发布
  • 从TTL到485:深入解析差分信号转换电路的设计要点与实战应用
  • 杭州GEO优化公司2026年6月Top5:选型疑问与避坑全解 - GEO优化

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号