CF570D Tree Requests

瑞芯微rv1126 rtsp+mpp+rga取流 瑞芯微rv1109 rtsp+mpp+rga取流 阅读详情

传送门

CF
luogu(目前无法提交,详见洛谷)
VJudge

题目大意

给定一颗以节点 1 1 1为根的树,包含 n n n个节点,每个节点上都有一个字符 c i c_i ci​。
特别的, 1 1 1号节点的深度为 1 1 1。
共有 m m m个问询,每次询问:在子树 v i v_i vi​中所有深度(相对于根) h i h_i hi​的所有节点能否构成回文串。

数据范围

  • 1 ≤ n , m ≤ 5 × 1 0 5 1\leq n,m\leq 5\times10^5 1≤n,m≤5×105
  • 1 ≤ v i , h i ≤ n 1\leq v_i,h_i\leq n 1≤vi​,hi​≤n

样例

输入输出样例 #1

输入 #1

6 5
1 1 1 3 3
zacccd
1 1
3 3
4 1
6 1
1 2

输出 #1

Yes
No
Yes
Yes
Yes

思路

dsu on tree 板子题。
首先分析构成回文串的要求,可以用一个cnt[dep][ch]数组统计当前子树中深度为 d e p dep dep的字符 c h ch ch出现次数。
离线统计问询中 v i = u v_i=u vi​=u的情况,在 dfs \text{dfs} dfs到子树 u u u1时只需将所有问询为 u , d u , j u,d_{u,j} u,du,j​对应的cnt[d_u,j][0~25]全部&=1再加到 r e s res res上,若最终 r e s ≤ 1 res\leq 1 res≤1则说明可以构成回文串。

例

6 5
1 1 1 3 3
zacccd
1 1
3 3
4 1
6 1
1 2

中,将1 1和1 2挂到节点1上处理

dsu on tree

由于空间限制,必须重复利用cnt数组,为此,在每颗树内,必须将其重儿子放在最后处理(dsu on tree),这样重儿子可以直接继承到原树,因为最后一个被枚举到的子树不会影响到后续,不用清空。
为什么需要清空子树呢?
虽然某颗不清空不会影响原树的统计,但是会影响到原树下的其他子树(在其后枚举的子树)
为了子树之间不影响,必须在dfs完清儿子后将其cnt清空。
在统计完最后一颗子树时,就要统计原树了。
此时再把前面的子树贡献加回来,补全原树。
最后特判根节点贡献就行了。

代码:

struct QUERY
{
	int id; // 此问询在问询列表中的位置
	int h;  // 此问询的查询深度
};
vector<QUERY> query[N]; // query[u]: 节点u的问询
vector<int> e[N]; // 原题输入给的是父亲表示法,此处转为儿子表示法
void merge(int u)
{
	++cnt[dep[u]][a[u]];
	for (auto j: e[u]) merge(j);
}
void delet(int u)
{
	--cnt[dep[u][a[u]]; // 或者直接等于0
	for (auto j: e[u]) delet(j);
}
// dfs1是树剖,用于确定重儿子和深度
dfs2(int u, bool ishvy) // 当前枚举到子树u,及是否为重儿子
{
	for (auto j: e[u]) { // 枚举u的儿子
		if (j == hson[u]) continue;
		dfs2(j, 0);
	}
	// 注意判断u是否为叶子节点,没有重儿子
	if (hson[u]) dfs2(hson[u], 1);
	for (auto j: e[u]) {
		if (j == hson[u]) continue;
		merge(j);
	}
	++cnt[dep[u]][a[u]];
	int check = 0;
	for (auto i: query[u]) {
		for (int j = 0; j < 26; ++j) check += cnt[i.h][j] & 1;
		if (check <= 1) ans = 1;
	}
	if (!ishvy) delet(u);
}

坑

写cnt的时候千万不要将cnt[i][j]错当成子树i了,我灵(脑)光(子)乍(抽)现(了)搞错了结果过了样例然后WA了TP2……

输入的时候要警惕#TP41,输入多打了一个回车,那些没有用

while (c == '\n || c == ' ') c = getchar();

的人估计就是这个点被HACK了
CF的hack机制还是太难绷了,居然有人用这种数据hack别人

完整代码

/*
AUTHOR: peter_code
DATE: 25/08/08
PROBLEM: CF570D
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int n, m, a[N];   // 节点数、问询数、节点权
vector<int> e[N]; // 节点i所有的儿子
int hson[N];      // 重儿子
int sz[N];        // 子树大小
int dep[N];       // 节点深度
bool ans[N];      // 记录"Yes"/"No"结果
int cnt[N][26];   // cnt[i][ch]: 深度为i,权为ch的节点出现次数

// 节点u上的问询维护:
struct QUERY
{
    int id;       // 第 id 个问询
    int h;        // 查询树中深度为h[i]的回文串构成情况
};
vector<QUERY> query[N];

int dfs1(int u, int d)
{
    hson[u] = 0;
    sz[hson[u]] = 0;
    dep[u] = d;
    sz[u] = 1;
    for (auto i: e[u]) {
        sz[u] += dfs1(i, d + 1);
        if (sz[i] > sz[hson[u]]) hson[u] = i;
    }
    return sz[u];
}
void merge(int u) // 合并根为u的子树
{
    ++cnt[dep[u]][a[u]];
    for (auto v: e[u]) merge(v);
}
void delet(int u) // 消除子树u的贡献
{
    cnt[dep[u]][a[u]] = 0;
    for (auto v: e[u]) delet(v);
}
void dfs2(int u, bool hvy) // 节点x,是否为重儿子(是否需保留信息)
{
    for (auto v: e[u]) {
        if (v == hson[u]) continue; // 优先处理轻儿子,重儿子最后处理
        dfs2(v, 0);
    }

    // 统计u重儿子的贡献(不会被清)
    if (hson[u]) dfs2(hson[u], 1); // 注意u为叶子节点无重儿子情况
    
    for (auto v: e[u]) {
        if (v == hson[u]) continue; // 重儿子已经统计过了
        merge(v); // 统计轻儿子贡献
    }
    ++cnt[dep[u]][a[u]]; // 特判根节点贡献
    
    // 统计挂在节点u上的答案
    //printf("In Sub-tree %d:\n", u);
    for (auto i: query[u]) {
        int res = 0;
        for (int j = 0; j < 26; ++j) {
            //printf("\tThere are %d '%c' on depth %d.\n", cnt[u][i.h]);
            res += cnt[i.h][j] & 1;
        }
        ans[i.id] = res <= 1;
    }
    if (!hvy) delet(u);
}
int main()
{
    //freopen("D.in", "r", stdin);
    scanf("%d%d", &n, &m);
    for (int i = 2; i <= n; ++i) {
        int tmp;
        scanf("%d", &tmp);
        e[tmp].push_back(i);
    }
    char c = getchar();
    while (c == '\n' || c == ' ') c = getchar();
    for (int i = 1; i <= n; ++i) {
        a[i] = c - 'a';
        c = getchar();
    }
    for (int i = 1; i <= m; ++i) {
        int tmpx, tmpy;
        scanf("%d%d", &tmpx, &tmpy);
        query[tmpx].push_back({i, tmpy});
    }
    dfs1(1, 1);
    dfs2(1, 1);
    for (int i = 1; i <= m; ++i) {
        if (ans[i]) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

后记

本人第一次写蓝题题解,若有不满,可在评论区提出,我一定尽力改正,谢谢!


  1. 除特殊说明外,文中子树 u u u皆表示以 u u u为根节点的子树 ↩︎

YOLOv11改进 | Conv篇 | 图像去雾卷积DEConv助力yolov11有效涨点(部署零额外开销) 本文介绍了一种最新改进机制用于低层视觉任务的细节增强卷积(DEConv)机制。DEConv在训练阶段采用"普通卷积+差分卷积"的多分支并联结构,增强网络对边缘、纹理等细节特征的学习能力;在推理阶段可折叠为标准3×3卷积,保持与普通卷积相同的计算效率。文中详细阐述了DEConv的工作原理、实现方法以及在YOLOv11中的应用步骤,包括核心代码解析、模型修改方法和训练配置。实验表明,该机制在去雾、去噪、超分等强调细节重建的任务中具有显著优势。文章还提供了完整的代码实现和训练指导. 阅读详情

相关推荐

Silly Tavern(酒馆)AI 角色扮演下载与安装教程(Windows本地部署)

SillyTavern是一款开源AI角色扮演前端工具,支持沉浸式对话和长期角色互动。本文详细介绍了在Windows系统F盘部署SillyTavern的完整流程,包括下载项目、安装Node.js和Git环境、配置路径、启动服务等关键步骤,并特别说明非系统盘路径可能遇到的npm安装问题及解决方法。成功启动后,用户可通过浏览器访问本地地址使用该工具进行AI角色扮演互动。

Tan3851的博客 1万+

cf570D Tree Requests

给一颗有根树,每个节点有一个字母,给m次询问,每次询问在i节点的子树下离根节点距离为d的所有节点的字母是否可以组合为回文串。 特别的,如果i节点下没有深度为d的节点都输出Yes。 我们统计每个节点下的子树所有深度的字母。用一个数组表示每个深度的26种字母。每次询问遍历26种字母如果总字母是奇数个且有两种及以上字母是出现了奇数次就肯定不能组合为回文串,偶数个字母必须都出现偶数次。...

ad4627的博客 160

二相混合式步进电机闭环矢量控制simulink仿真(含仿真文件)

在位置跟踪伺服系统中二相混合式步进电机闭环矢量控制simulink仿真

qq_39023633的博客 2万+

cf570 D. Tree Requests

cf570 D. Tree Requests 题意: 给定一个以 1 为根的 n 个结点的树,每个点上有一个字母(a-z)。每次询问 a, b 查询以 a 为根的子树内深度为 b 的结点上的字母重新排列之后是否能构成回文串。 题解: 回文串形成条件? 如果回文串是偶数个,那就要求每个字符都是出现偶数次 如果回文串是奇数个,那么说明只有一个字符是奇数次,其他都是偶数次 总结:最后只能有一个字符出现奇数次 现在我们开始统计一个子树内的各字符出现次数,可以用树上启发式合并来做,因为有q组询问,对于每组询问我们存下

qq_35975367的博客 487

STM32固定翼增稳飞控设计:姿态解算、双环PID与一键救机实现

姿态稳定控制是无人机与航模飞控系统的核心基础,其本质是通过传感器融合(如IMU)实时感知飞行器姿态,并基于控制理论(如PID)生成修正指令以抑制扰动。该技术广泛应用于教育航模、轻型固定翼平台及嵌入式飞控开发场景,具有低延迟、高确定性、资源敏感等典型工程特征。本文围绕STM32F401与MPU6050构建的硬件闭环系统,深入解析互补滤波姿态解算原理与俯仰/横滚双环PID控制结构,同时聚焦‘一键救机’这一面向新手的关键安全机制——通过分阶段角速率抑制与平滑角度拉平策略,在80ms内启动响应,显著提升飞行容错能力

weixin_36328210的博客 400

别再手动抓波形了!用Synopsys AXI VIP的Port Monitor自动收集事务数据(附完整连接Scoreboard代码)

当标准Port Monitor无法满足需求时,Synopsys提供的callback机制就像一套精密的手术工具,允许你深入VIP内部进行定制化改造。创建自定义监控点的四步法继承基类// 其他自定义字段...endclass重写目标phase方法// 克隆事务并发送到自定义端口在env中注册callbackcustom_cb);连接自定义端口到分析组件经典应用场景地址phase特定检查数据beat级监控自定义性能统计异常注入检测。

weixin_28716181的博客 397

【CF 570D】Tree Requests

【CF 570D】Tree Requests树节点标号递增 规定父亲标号<儿子 dfs重标号 同时用一个数组存该节点为根的树的最小节点 一个数组存该节点为树根的最大节点 一个数组存对应深度存在的节点 再来一个数组存每一位置累计字符(26个字符 由于偶数次可压缩 故用异或即可) 每查询一个节点和他对应的深度 只需在该深度查该节点为根的最小和最大节点 然后用左右节点字符累计数互相异或 最后看它二进

ACMer' 1087

CVPR 2027 投稿规划:基于近3年录用率与截稿周期的5步时间管理法

本文为计算机视觉研究者提供CVPR 2027投稿的完整规划指南,基于近三年录用率与截稿周期数据,提出五步时间管理法。涵盖选题策略、实验设计、论文写作、同行评审到最终提交的全流程优化,特别针对CVPR日益激烈的竞争环境(2024年投稿量达11532篇,录取率仅23.6%)提供实用解决方案,帮助研究者提升投稿成功率。

weixin_34079177的博客 1148

【cf 570d】Tree Requests

【cf 570d】Tree Requests

pbihao的博客 430

Zemax热分析实战:5分钟搞定双胶合透镜温度漂移优化(附操作数详解)

本文详细解析了使用Zemax进行光学系统热分析的全流程,以双胶合透镜为例,重点阐述了如何通过多重结构编辑器模拟温度变化,并利用关键操作数优化系统以抵抗温度漂移。文章提供了从基础设置到高级优化的实战技巧,帮助工程师快速掌握无热化设计方法,确保系统在宽温范围内保持稳定成像性能。

n4o5p6q7r的博客 396

C++ 程序稳定运行一段时间后异常中止?vc6 运行库的bug!!!

事件查看器提示:错误应用程序 xxxxxxx.exe,版本 0.0.0.0,错误模块 MSVCRTD.DLL,版本 6.0.9782.0,错误地址 0x00012b40。这是一个通信方面的软件,需要长期运行,在压力测试时,高负荷连续运行一定天数时必定崩溃,而且都是在msvcrtd.dll中崩溃。后来在dump文件中发现调用栈在是MSVCRTD.DLL模块,跟踪代码发现是在void * __cdecl _heap_alloc_dbg(        size_t nSize,        int nBloc

qingflying的专栏 2679

[CF570D]Tree Requests

Codeforces 数据结构

YveH 736

从0入门LocoTrack:6倍加速的SLAM追踪新范式实战指南

传统点追踪方法(如CorrTracker、TAPIR)在处理大规模场景或实时任务时,要么精度不足,要么速度太慢。而LocoTrack通过“局部4D相关性”和“Transformer全局关联”的创新设计,实现了精度与速度的双重突破速度:比现有SOTA方法快6倍,吞吐量高达数万点/秒;精度:在Kinetics、DAVIS等数据集上,定位误差显著低于传统方法;鲁棒性:能应对低纹理、动态场景等复杂环境,这是传统方法的“噩梦场景”。

m0_71589036的博客 95

CF570D-Tree Requests【长链剖分】

正题 题目链接:https://www.luogu.com.cn/problem/CF570D 题目大意 nnn个点的一棵树,每个节点有字母,每次询问一个节点xxx的子树中深度为kkk的所有点的字母能否经过重排构成一个回文串。 解题思路 首先把每个字母的奇偶状压一下 然后方法比较多,一些就粗略的提一下 长链剖分 设fi,jf_{i,j}fi,j​表示节点iii中距离jjj的节点状态,然后这个是根据深度会转移的,上长链剖分即可。 时间复杂度O(n)O(n)O(n) 二分+vector+vector+vec

QuantAsk 465

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

CF570D - Tree Requests 树上启发式合并

CF570D - Tree Requests 题意 NNN个点以111为根的树,每个节点都有对应的字母s[i]s[i]s[i],MMM次查询,每次判断以uiu_iui​为根的子树中,深度为hih_ihi​的节点能否组成一个回文串(字母顺序可以任意改变),如果能输出Yes,否则输出No 分析 树上启发式合并入门题,查询的子树信息就是对应高度都有什么字母 因为这里节点的顺序能够改变,所以构成回文串只需...

流水 390

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

CF570D Tree Requests(dsu on tree)

题解: dsu on tree 首先dsu on tree是一个离线的算法,所以我们需要先把他们的询问储存起来,然后进行操作。 针对于每一个结点,我们先统计出他和他子树的所有信息,然后对于这个结点来说,我们已经把对于这个结点要查询的信息统计下来了,我们去暴力查询一下这个结点下深度每个字母的个数即可,对于出现次数为奇数的字母,我们最多可以允许有一个这样的字母(回文串放在中间)。最后输出即可。 代码: /*Keep on going Never give up*/ //#pragma GCC optimize(

xxxxxiao123的博客 185

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

CF 570 D. Tree Requests

D. Tree Requests http://codeforces.com/problemset/problem/570/D 题意:   一个以1为根的树,每个点上有一个字母(a-z),每次询问一个子树内深度为h的点是否可以构成回文串。(深度是到1的深度,没有也算,空回文串) 分析:   dsu on tree。询问子树信息。   判断是否构成回文:出现奇数次的字符小于等于1个。 ...

weixin_30325793的博客 127

CF570D Tree Requests(dsu---板子题)

传送门 使用数组cnt[i][j]cnt[i][j]cnt[i][j]表示当前子树内,深度iii字母为jjj的有多少个 那么可以开始dsudsudsu,这样与uuu有关的所有询问都可以快速得出解 差不多就是板子了 储存询问用vecvecvec或链式前向星 #include <bits/stdc++.h> using namespace std; const int maxn = 5e5+19; struct edge{ int to,nxt; }d[maxn]; int head[maxn],

jziwjxjd的博客 539

cf570D. Tree Requests(dsu on tree)

Roman planted a tree consisting of n vertices. Each vertex contains a lowercase English letter. Vertex 1 is the root of the tree, each of the n - 1 remaining vertices has a parent in the tree. Vertex i

Coco_T的博客 375

CF 570D. Tree Requests [dsu on tree]

传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... 一开始dfs没有判断重儿子T了一次 #include &lt;iostream&gt; #include &lt;cstdio&gt; #include &lt;cstring&gt; #incl...

weixin_34258782的博客 152

【树上启发式合并】CF570D Tree Requests(对点)

CF570D Tree Requests(树上启发式合并+对点) 题意: 给定一个以 1 为根的 n 个结点的树,每个点上有一个字母(a-z),每个点的深度定义为该节点到 1 号结点路径上的点数。每次询问 a, b 查询以 a 为根的子树内深度为 b 的结点上的字母重新排列之后是否能构成回文串。 思路: 一层结点的字母是否能组成回文串,只需观察每个字母出现次数要么都是偶数,要么只有一个字母奇数次出现。 #include<bits/stdc++.h> using namespace std; t.

weixin_45722843的博客 196
上一篇: C++埃氏筛
下一篇: [USACO25OPEN] Election Queries G 题解
peter_code
博客等级 码龄5年 41粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值