解题:CF570D Tree Requests】的更多相关文章

题面 DSU on tree确实很厉害,然后这变成了一道裸题(逃 还是稍微说一下流程吧,虽然我那个模板汇总里写过 DSU on tree可以以$O(n\log n)$的复杂度解决树上子树统计问题,它这样工作: 前置工作:对树进行轻重链剖分 1.递归求解所有的轻儿子,在回溯时消去影响 2.递归进入重儿子,在回溯时不消去影响 3.暴力统计子树信息 4.回答询问并回溯 根据轻重链剖分的性质,复杂度$O(n\log n)$ #include<cstdio> #include<vector>…
1.题目大意:给你一棵树,每个点有一个字符,然后我们定义1的深度是1,然后1的儿子深度是2... 然后有一个询问,询问以i为根节点的子树,然后深度是k的那层的所有字符,可否组成一个回文串 2.分析:首先来考虑一下回文串的性质,有什么性质呢,就是里面出现次数为奇数次的点一定不会超过1个, 否则我们一定可以弄出回文串,对吧 那么我们离线处理这个东西,我们首先建立dfs序线段树,线段树里啥也别存,然后我们将询问的操作按k的大小排序 对于k相同的操作,我们在一起处理,k最多不会超过n,对吧,我们怎么处理…
离线 + 树状数组 如果子树中的一个深度的所有点中有两个以上的字母出现了奇数次,那么这个询问的答案就是$No$,其他的情况吧都是$Yes$. 由于只有$26$个字母,我们可以考虑暴力检验,把树映射到$dfs$序上然后看一看子树区间中每一个字母出现了多少次. 我先写了一个动态开点的线段树,然后$O(26 * (n + q)logn)$完美爆炸了. 然后我们发现一个深度的所有点是可以相互利用的,这样子只要堆所有的询问离线一下按照深度排个序就好了,开$26$个树状数组单点修改+ 区间求和就做完了. 感…
题目链接: 570 D. Tree Requests 题目描述: 给出一棵树,有n个节点,1号节点为根节点深度为1.每个节点都有一个字母代替,问以结点x为根的子树中高度为h的后代是否能够经过从新排序变成一个回文串? 解题思路: 判断是不是回文串,可以统计集合中出现过的字母的个数,出现奇数次的字母个数小于1,即为回文串,否则不是.所以我们可以使用状压统计当前区间中字母出现的奇偶次数. 对于如何快速的求出区间,先dfs整棵树,标记下来每个节点进栈的时间和出栈的时间,然后把高度一样的点按照进栈时间顺序…
D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Roman planted a tree consisting of n vertices. Each vertex contains a lowercase English letter. Vertex 1 is the root of the…
D. Tree Requests http://codeforces.com/problemset/problem/570/D 题意: 一个以1为根的树,每个点上有一个字母(a-z),每次询问一个子树内深度为h的点是否可以构成回文串.(深度是到1的深度,没有也算,空回文串) 分析: dsu on tree.询问子树信息. 判断是否构成回文:出现奇数次的字符小于等于1个. 代码: #include<cstdio> #include<algorithm> #include<cst…
http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Roman planted a tree consisting of n vertices. Each vertex contains a lowercase…
570D - Tree Requests 题意 给出一棵树,每个节点上有字母,查询 u k,问以 u 为根节点的子树下,深度为 k 的所有子节点上的字母经过任意排列是否能构成回文串. 分析 一个数组 \(C[i][j]\) 表示深度为 \(i\) 字母为 \(j\) 的数量,数组 \(odd[i]\) 表示深度为 \(i\) 时出现次数为奇数的字母种数. 如果想要构成回文串,那么某一深度下出现的次数为奇数的字母不能超过一种,注意如果字符串长度为 0 也叫回文串. code #include<bi…
链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Roman planted a tree consisting of n vertices. Each vertex contains a low…
链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 (u, deep) 问u点的子树中,距离根的深度为deep的全部点的字母是否能在随意排列后组成回文串,能输出Yes. 思路:dfs序,给点又一次标号,dfs进入u点的时间戳记为l[u], 离开的时间戳记为r[u], 这样对于某个点u,他的子树节点相应区间都在区间 [l[u], r[u]]内. 把距…
传送门 DFS重标号+二分 打比赛的时候想了很多方法..DFS序,BFS序,倍增什么的都考虑了一遍,但是几乎要么是可以维护两个区间但是代码复杂度爆炸,要么就是只能维护单一维度的信息. 这道题的具体做法就是先DFS遍历一遍,记一下每个点的出入栈时间.按照每个点的深度排序.这样就可以二分出深度,然后根据入栈的时间可以再在这个深度内二分出合适的区间.范围就是询问节点的出入栈时间. //CF 570D //by Cydiater //2016.10.14 #include <iostream> #in…
题目链接:codeforces570D 正解:$dsu$ $on$ $tree$ 解题报告: 考虑这又是一类子树内的不带修改统计问题,直接上$dsu$ $on$ $tree$好咯. 直接按上一道题的做法做,类似地存一下每个深度每种字符的出现次数,对于每个点的询问,在每个点处查询一下就好了,只需奇数的个数$<=1$即可. //It is made by ljh2000 //有志者,事竟成,破釜沉舟,百二秦关终属楚:苦心人,天不负,卧薪尝胆,三千越甲可吞吴. #include <iostream&…
传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... 一开始dfs没有判断重儿子T了一次 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using names…
D time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output 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…
题意:给出一棵树.每一个结点都有一个字母,有非常多次询问,每次询问.以结点v为根的子树中高度为h的后代是否可以经过调整变成一个回文串. 做法: 推断能否够构成一个回文串的话,仅仅须要知道是否有大于一个的奇数数目的字母就可以.为了非常快的訪问到一个区间.记录前缀和就可以.为了省内存,状压奇偶就可以. 为了非常快的找到以结点v为根的子树中高度为h的后代,须要dfs整棵树.然后记录每一个结点第一次訪问它的时间戳以及离开它的时间戳,就能够二分出来. 为了省内存,能够离线处理询问. #include<ma…
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output 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\)为根的有根树.之后有\(m\)个询问,每个询问为\(v_i,h_i\),需要回答以\(v_i\)为根的子树中,深度为\(h_i\)的那些结点所代表的字符能否构成回文串. 思路: 静态子树询问,考虑\(dsu\ on\ tree\). 深度可以提前处理出来.对一个子树处理时,用一个数组\(d[deep][cnt]\)来记录. 最后直接根据深度枚举判断即可. 正确性的话是基于算法本身的,我们考虑一个子树时,数组中目前只会储存这颗子树内部的信息. /* * Auth…
http://codeforces.com/contest/570/problem/D 给一棵有根树(50w个点)(指定根是1号节点),每个点上有一个小写字母,然后有最多50w个询问,每个询问给出x和f,表示询问以x为根的子树,在第f层的所有节点上的字符能否组成一个回文串 首先树形转线性,把每个点按照DFS序重新标号,然后开个vector记下第i层都有哪些节点, 对于这一层的节点,维护一个前缀和,即某个字母出现过多少次, 这样对于某个询问x,f,我们能知道x为根的子树在线性数组中的序号范围, 然…
题目链接:https://codeforces.com/problemset/problem/570/D 题解: 这种题,基本上容易想到DFS序. 然后,我们如果再把所有节点分层存下来,那么显然可以根据 $in[v],out[v]$ 在层内二分出一段属于 $v$ 的子树的节点. 那么我们进一步考虑,如果把一层的节点,按 $a \sim z$ 再分开来,用一个 $S[c][d]$ 数组来存所有字母为 $c$,深度为 $d$ 的节点的 $in[]$ 值. 这样一来,对于一个询问 $v,h$,就在 $…
大意: 给定树, 每个节点有一个字母, 每次询问子树$x$内, 所有深度为$h$的结点是否能重排后构成回文. 直接暴力对每个高度建一棵线段树, 查询的时候相当于求子树内异或和, 复杂度$O((n+m)log(n+m))$ 看了别人题解后发现有简单做法, 高度相同的点在每个子树内的dfs序一定相邻, 直接维护每一层的异或和, 每次二分出该层属于$x$的子树的一段区间即可. 放一下线段树暴力的代码 #include <iostream> #include <algorithm> #in…
参考九野巨巨的博客. 查询一个子树内的信息,可以通过DFS序转成线形的,从而用数据结构来维护. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #define MP make_pair #define FI first #define SE second using namespace std; typedef…
[题目大意]: 给定一棵树,树的每个节点对应一个小写字母字符,有m个询问,每次询问以vi为根节点的子树中,深度为hi的所有节点对应的字符能否组成一个回文串: [题目分析]: 先画个图,可看出每次询问的所有节点都是一个从1开始bfs遍历完成的节点序列中的一段,已知深度hi的情况下,可以二分得到深度为hi的那一段的位置: 那么如何满足找到的节点必须在以vi为根的子树内这个条件? 可以想到dfs的时间戳,把1-n的数组按深度排序,深度相同的按照dfs时间戳排序: 这样就可以二分得到要求的所有节点的位置…
官方题解是离线询问,dfs树形转线性,然后二分找区间. 还有一种比较好的做法是直接dfs,将当前访问这个结点u相关的询问之前的状态存起来,然后访问完以后利用异或开关性,得到这颗子树上的答案. 代码是学习别人的http://blog.csdn.net/squee_spoon/article/details/47666667 #include<bits/stdc++.h> using namespace std; ; char s[maxn]; int head[maxn],to[maxn],nx…
题目链接 题意:对于m次询问 求解以vi为根节点 深度为hi的的字母能不能组合成回文串. 思路:暴力dsu找一边 简直就是神技! #include<bits/stdc++.h> #define ll long long int using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} int moth[13]={0,31…
近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数)的不二法宝.它不仅好想好写,还有着\(O(nlogn)\)的优秀时间复杂度(划重点). 结合一道例题来讲吧: CF600E Lomsat gelral 题目大意: 一棵树有\(n(n\leqslant 10^5)\)个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和…
[dsu on tree][学习笔记] - Candy? - 博客园 题单: 也称:树上启发式合并 可以解决绝大部分不带修改的离线询问的子树查询问题 流程: 1.重链剖分找重儿子 2.sol:全局用桶或者数据结构存信息. ①递归所有的轻儿子,回溯前删除贡献 ②递归重儿子,不删除贡献 ③暴力找所有轻儿子,加入贡献 ④更新x的答案 ⑤如果x是父亲的轻儿子,再把整个子树贡献删除(信息只有子树的,有时可以不用再dfs去重,可以直接清空) 正确性: 一个点的轻儿子会暴力更新到所有信息,重儿子链不会删除贡献…
dsu on tree 树上启发式合并.我并不知道为什么要叫做这个名字... 干什么的 可以在\(O(n\log n)\)的时间内完成对子树信息的询问,可横向对比把树按\(dfs\)序转成序列问题的\(O(n\sqrt n)\)莫队算法. 怎么实现 当\(dfs\)到一个点\(u\),执行以下操作: 1.递归处理所有轻儿子; 2.递归处理重儿子; 3.计算整棵子树的贡献(在第2步中重儿子的贡献得以保留,所以不需要重复计算); 4.若点\(u\)不是其父亲的重儿子,删除整棵子树的贡献. 看上去像是…
参考资料 https://www.cnblogs.com/zhoushuyu/p/9069164.html https://www.cnblogs.com/candy99/p/dsuontree.html https://www.cnblogs.com/zcysky/p/6822395.html 简介 树上启发式合并 用到了heavy−light decomposition树链剖分 把轻边子树的信息合并到重链上的点里 因为每次都是先dfs轻儿子再dfs重儿子,只有重儿子子树的贡献保留,所以可以保…
dsu on tree. \(\rm 0x01\) 前言\(\&\)技术分析 \(\bold{dsu~on~tree}\),中文别称"树上启发式合并"(虽然我并不承认这种称谓),大概是一种优雅的暴力,并且跟\(dsu\)毫无关系.于是我打算叫他\(\bold{Elegantly~Direct~Counting~on~Tree}\),"优雅的树上暴力统计". 严格来说,\(\bold {EDCT}\)解决的问题范围并不广泛: 1.维护子树信息: 2.不能带修改…
前言 一次模拟赛的\(T3\):传送门 只会\(O(n^2)\)的我就\(gg\)了,并且对于题解提供的\(\text{dsu on tree}\)的做法一脸懵逼. 看网上的其他大佬写的笔记,我自己画图看了一天才看懂(我太蒻了),于是就有了这篇学习笔记. 概念篇/基础运用 算法简介 现在考虑这样一类树上统计问题: 无修改操作,询问允许离线 对子树信息进行统计(链上的信息在某些条件下也可以统计) 树上莫队?点分治? \(\text{dsu on tree}\)可以把它们吊起来打! \(\text{…