CF570D——Tree Requests
1、题目大意:给你一棵树,每个点有一个字符,然后我们定义1的深度是1,然后1的儿子深度是2...
然后有一个询问,询问以i为根节点的子树,然后深度是k的那层的所有字符,可否组成一个回文串
2、分析:首先来考虑一下回文串的性质,有什么性质呢,就是里面出现次数为奇数次的点一定不会超过1个,
否则我们一定可以弄出回文串,对吧
那么我们离线处理这个东西,我们首先建立dfs序线段树,线段树里啥也别存,然后我们将询问的操作按k的大小排序
对于k相同的操作,我们在一起处理,k最多不会超过n,对吧,我们怎么处理呢,首先线段树里的空的,
线段树里的每一个节点都是一个存26个字符的出现次数的数组
我们把所有第k层的数的字符都扔进线段树,那么我做这些询问的时候,我可以找到一颗子树对应的区间,对吧
但是这个区间里只有第k层的数在这里面存着,那么我查询这个区间就相当于查询以i为根节点的子树,深度是k的那层
对吧,之后我们返回一个存26个字符的出现次数的数组。但是这样的时间复杂度是26nlogn的对吧,虽然可以卡过,
但是还是保险的好。。。我们怎么办呢,状压,我们利用异或的半加性质,我们可以把线段树的每一个节点改成状压的
仔细想一下。。
然后我们的复杂度退化到nlogn
这样就可以完美的通过了,(最不习惯写离线的算法了
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; int head[600000], ne[600000], v[600000]; int first[600000], nx[600000]; int le[600000], ri[600000], ll; char str[600000]; int tot; int ans[600000]; struct node{ int num, dep, id; bool operator < (const node& rhs) const{ return dep < rhs.dep; } }; node a[600000]; struct segment_tree{ int q[2500000]; int x, y; inline void add(int l, int r, int o){ if(l == r && l == x){ q[o] = y; return; } int mid = (l + r) / 2; if(x <= mid) add(l, mid, 2 * o); if(x > mid) add(mid + 1, r, 2 * o + 1); q[o] = q[2 * o] ^ q[2 * o + 1]; return; } inline int query(int l, int r, int o){ if(x <= l && r <= y){ return q[o]; } int mid = (l + r) / 2; int ret = 0; if(x <= mid) ret ^= query(l, mid, 2 * o); if(y > mid) ret ^= query(mid + 1, r, 2 * o + 1); return ret; } } wt; inline void dfs(int x, int h){ nx[x] = first[h]; first[h] = x; le[x] = ++ ll; for(int i = head[x]; i != -1; i = ne[i]){ dfs(v[i], h + 1); } ri[x] = ll; return; } int main(){ memset(head, -1, sizeof(head)); memset(first, -1, sizeof(first)); int n, m; scanf("%d%d", &n, &m); for(int i = 2; i <= n; i ++){ scanf("%d", &v[i]); ne[i] = head[v[i]]; head[v[i]] = i; v[i] = i; } dfs(1, 1); scanf("%s", str); for(int i = 1; i <= m; i ++){ scanf("%d%d", &a[i].num, &a[i].dep); a[i].id = i; } sort(a + 1, a + m + 1); int i = 1; for( ; i <= m; ){ int height = a[i].dep; for(int j = first[height]; j != -1; j = nx[j]){ wt.x = le[j]; wt.y = (1 << (str[j - 1] - 'a')); wt.add(1, n, 1); } for( ; i <= m && a[i].dep == height; i ++){ wt.x = le[a[i].num]; wt.y = ri[a[i].num]; int hh = wt.query(1, n, 1); int cnt = 0; for(int k = 0; k <= 25; k ++) if(((1 << k) & hh)){ cnt ++; } if(cnt > 1) ans[a[i].id] = 0; else ans[a[i].id] = 1; } for(int j = first[height]; j != -1; j = nx[j]){ wt.x = le[j]; wt.y = 0; wt.add(1, n, 1); } } for(int j = 1; j <= m; j ++){ if(ans[j] == 1) printf("Yes\n"); else printf("No\n"); } return 0; }
CF570D——Tree Requests的更多相关文章
- 解题:CF570D Tree Requests
题面 DSU on tree确实很厉害,然后这变成了一道裸题(逃 还是稍微说一下流程吧,虽然我那个模板汇总里写过 DSU on tree可以以$O(n\log n)$的复杂度解决树上子树统计问题,它这 ...
- CF570D Tree Requests
离线 + 树状数组 如果子树中的一个深度的所有点中有两个以上的字母出现了奇数次,那么这个询问的答案就是$No$,其他的情况吧都是$Yes$. 由于只有$26$个字母,我们可以考虑暴力检验,把树映射到$ ...
- Codeforces Round #316 (Div. 2) D. Tree Requests dfs序
D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- CF 570 D. Tree Requests
D. Tree Requests http://codeforces.com/problemset/problem/570/D 题意: 一个以1为根的树,每个点上有一个字母(a-z),每次询问一个子树 ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组 异或
http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...
- Codeforces 570D - Tree Requests(树上启发式合并)
570D - Tree Requests 题意 给出一棵树,每个节点上有字母,查询 u k,问以 u 为根节点的子树下,深度为 k 的所有子节点上的字母经过任意排列是否能构成回文串. 分析 一个数组 ...
- codeforces 570 D. Tree Requests 树状数组+dfs搜索序
链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...
- codeforces 570 D. Tree Requests (dfs)
题目链接: 570 D. Tree Requests 题目描述: 给出一棵树,有n个节点,1号节点为根节点深度为1.每个节点都有一个字母代替,问以结点x为根的子树中高度为h的后代是否能够经过从新排序变 ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组
链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 ...
随机推荐
- oneM2M标准发展神速 实现万物联网的愿景
http://m2m.iot-online.com/news/2013102224849.html oneM2M则将负责解决独立于接取网路中通用的M2M服务层的关键需求:使其可更方便地嵌入于各种软硬体 ...
- SQL Server编程(01)流程控制
批处理 应用程序向SqlServer发送的一组命令,Sql Server会将其编译成一个可执行单元,称为执行计划,执行计划中的语句每次执行一条. 每个不同的批处理用GO命令分割.GO命令不是SQL语句 ...
- context.Request.Files为NULL问题 在实现图片上传功能的时候出现在ashx等处理页面出现context.Request.Files为NULL异常,有几点需要注意:
.在客户端可以将form用submit提交,如下: <%@ Page Language="C#" AutoEventWireup="true" CodeF ...
- 转:遗传算法解决TSP问题
1.编码 这篇文章中遗传算法对TSP问题的解空间编码是十进制编码.如果有十个城市,编码可以如下: 0 1 2 3 4 5 6 7 8 9 这条编码代表着一条路径,先经过0,再经过1,依次下去. 2.选 ...
- 加载信息,先从数据库取出5条实现分页,鼠标向上滑动触发Ajax再加载5条,达到异步刷新,优化加载。。。
php数据库取数据 <?php include("conn1.php"); include('../function/functions.php'); $page=intva ...
- UILabel UISwitch UISegmentedControl UIAlertView
基础小控件 /***************************************UIlabel*************************************/ UILabel ...
- Java——字符集:Charset
- (转)Java API设计清单
转自: 伯乐在线 Java API设计清单 英文原文 TheAmiableAPI 在设计Java API的时候总是有很多不同的规范和考量.与任何复杂的事物一样,这项工作往往就是在考验我们思考的缜密程度 ...
- Deep Learning in a Nutshell: History and Training
Deep Learning in a Nutshell: History and Training This series of blog posts aims to provide an intui ...
- 《css3实战》读书笔记 第一章 基于CSS需求而编写的HTML.
笔记说明 <CSS3实战手册第3版(影印版)>可以消除Web设计工作的痛苦,并且带给你:HTML--重新入门.如果你是HTML新手,你会学到如何以CSS友好的方式进行基本页面构造.若你是H ...