C. 【UNR #3】配对树】的更多相关文章

[UOJ#388][UNR#3]配对树(线段树,dsu on tree) 题面 UOJ 题解 考虑一个固定区间怎么计算答案,把这些点搞下来建树,然后\(dp\),不难发现一个点如果子树内能够匹配的话就一定会匹配完,所以\(dp\)可以做到线性. 那么根据上面的\(dp\)方式,一条边会被匹配到,当且仅当把这条边删掉之后,两个连通块内分别有奇数个目标点.那么如果我们考虑枚举每一条边,然后把子树内的点给标记一下,于是变成了在原序列上求有多少个偶数区间满足有偶数个点被标记,这个问题可以做一个前缀和,把…
uoj description 给你一棵\(n\)个节点的树以及一个长为\(m\)的序列,序列每个位置上的值\(\in[1,n]\),你需要求出把序列中所有长度为偶数的区间内所有数拿出来在树上以最小代价匹配的代价之和模\(998244353\). sol 首先拿出偶数个点在树上匹配这个问题,根据贪心,我们一定会让这些点在尽可能深的位置匹配.换句话说,每棵子树中未匹配的点至多只有一个. 那么我们考虑每一条边,这一条边会被计算贡献当且仅当这条边连接的子树里有奇数个选出的点. 那么我们相当于是要求对于…
传送门 先考虑一个贪心,对于一条边来说,如果当前这个序列中在它的子树中的元素个数为奇数个,那么这条边就会被一组匹配经过,否则就不会 考虑反证法,如果在这条边两边的元素个数都是偶数,那么至少有两组匹配经过它,那么把这两条路径都删去这条边可以更优.如果两边是奇数,一定至少有一条路径经过它,去掉这组匹配之后就变成了偶数的情况.证毕 然后是一个神仙的转化,我们对于一颗子树中的元素,在序列里标记为\(1\),否则为\(0\),那么这条边出现次数就是序列中长度为偶数且区间和为奇数的区间个数 考虑用线段树合并…
题解: 首先可以贪心 于是问题可以等价成一条边被算当且仅当子树中个数为奇数个 题解的做法比较简单 考虑每条边,加入其子树内的点 然后为了保证区间长度为偶数 分成f0,0 f0,1 f1,0 f1,1即可 暴力插入复杂度不对改成启发式合并即可 这里插入的时候可用线段树维护 把x-n这一段翻转即可 这样是两个log 一般可以用线段树合并优化启发式合并 但是这里改成线段树合并的话要换一种维护方式 我们维护左儿子ddl的个数来决定右儿子中的信息是直接加还是需要翻转 这样就可以线段树合并了 复杂度一个lo…
传送门 题意: 给出一颗含有\(n\)个结点的无根树,之后给出一个长度为\(m\)的序列,每个元素在\([1,n]\)之间. 现在序列中每个长度为偶数的区间的完成时间定义为树上最小配对方法中每对匹配点间距离的总和. 现在要求所有长度为偶数的区间的完成时间的和. 思路: 首先不妨将这颗树转化为有根树,最终不会影响答案. 注意到性质:偶数个点的两两匹配方式是唯一的,都是最深的两个点相互匹配,这样才能保证没有重复计算的边. 在子树内部直接计算不好算,要考虑很多东西(一开始就想偏了QAQ).因为匹配方式…
题解 贪心+线段树 首先如果我们知道了哪些点是关键点应该怎么搞 显然最小的匹配方案所有的边至多被经过一次 可以考虑每条边的贡献 因为我们要贡献尽量小 所以我们尽量让每条边经过的人尽量少 那么每条边被经过的条件就是一条边连接的两个节点的子树内关键点数量是奇数 然后我们可以直接考虑每条边会被多少个区间影响 一条边能被一个区间影响的条件就是这个区间的大小是偶数且这个区间内在这个边的深度较深的端点的子树内的点的数量有奇数个 也就是满足\(j-i=0(\mod 2) s_j - s_i=1(\mod 2)…
地址:http://uoj.ac/contest/45 第一题是鸽子固定器. 只会10分.按 s 从小到大排序,然后 dp[ i ][ j ][ k ] 表示前 i 个元素.已经选了 j 个.最小值所在位置是 k 的最大代价. #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; int rdn() { ;;char ch=getc…
赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noip前的杂题训练,我也很无奈啊 做完了的扔最后,欢迎好题推荐 这么多题肯定是完不成了,能多做一道是一道吧 DP yyb真是强得不要不要的辣:http://www.cnblogs.com/cjyyb/category/1036536.html [ ] [SDOI2010]地精部落 https://www…
[UNR #1]火车管理(主席树) 好好的代码被 \(extra\ test\) 卡常了...我就放一个目前最快的版本吧... 题意简化: 有 \(n\) 个栈,\(m\) 次操作. 将 \(x\) 压入 \([l,r]\) 的栈中 将 \(l\) 的栈顶弹出 询问 \([l,r]\) 栈顶的和 \(n,m\leq 5\times 10^5\) 虽然最优解是神仙二叉树,我只会主席树的解法... 显然 \(1,3\) 操作用一棵线段树就够了,\(2\) 操作需要另外一棵主席树,并且在历史版本上修改…
「UNR#1」奇怪的线段树 一道好题,感觉解法非常自然. 首先我们只需要考虑一次染色最下面被包含的那些区间,因为把无解判掉以后只要染了一个节点,它的祖先也一定被染了.然后发现一次染色最下面的那些区间一定是一段连续的左儿子+一段连续的右儿子. 证明的话可以看官方题解,感性理解的话不难,同时,任意一段连续的左儿子+右儿子也对应一个区间.定义一个左儿子区间 \([l_i,r_i]\) 的后继是所有 \(r_i=l_i+1\) 的左儿子和右儿子,一个右儿子区间 \([l_i,r_i]\) 的后继是所有…
题目 https://www.luogu.com.cn/problem/P5677 分析 最开始读题的时候没有读的太懂,以为i是在选定区间内给的,实际上不是,这道题的意思应该是在l和r的区间内找出有多少个好的配对,这里好的配对是对于整个区间来说的,既然是对于整个区间,我们就不难想到找出好的配对的方法,所以我们可以先找出所有好的配对,然后用树状数组维护个数. 如何找出好的配对呢?我们先来分析什么叫好的配对,选定的两点间距离比其中一点到除对方外任意一点的距离都小,也就是说这两点差的绝对值最小,这样的…
来自FallDream的博客,未经允许,请勿转载, 谢谢. 原题可以到UOJ看,传送门 如果存在一个点是白的,却有儿子是黑的,显然无解. 不然的话,只要所有黑色的“黑叶子”节点,即没有黑色的儿子的节点有访问到就行了. 联想到今年CTSC上一道题叫“被操纵的线段树”,每个点被访问之后,可以和他合并的点满足左端点是它的右端点+1,并且和它没有相同的父亲. 发现这些点构成一条链,所以只需要向最大的那个点连边就行了,然后每个点向左儿子连边. 拆点之后,给所有的“黑色叶子”节点中间的边加上流量下界,求出最…
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ218.html 题解 如果我们可以知道每次弹出栈之后新的栈顶是什么,那么我们就可以在一棵区间覆盖.区间求和的线段树上完成这个问题. 于是本题的重点转到了如何求新的栈顶. 考虑用一个主席树维护一下每一个时刻每一个位置的栈顶元素的进栈时间,那么新的栈顶就是 当前位置栈顶的进栈时间-1 这时候的栈顶元素,然后这个东西也可以用我们维护的进栈时间来得到,所以我们只需要弄一个支持区间覆盖单点查询历史版本的主席树:这…
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1737 题意: 思路: 树的重心. 树的重心就是其所以子树的最大的子树结点数最少,删除这个点后最大连通块的结点数最小,也就说各个连通块尽量平衡. 这道题的话就是先求一个重心,然后求各个点到重心的距离之和. #include<iostream> #include<algorithm> #include<cstring> #include<cs…
用可持久化线段树维护每个站的第一辆车和每个站的前一次更新的位置即可. #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<algorithm> #define maxn 500005 using namespace std; inline int read() { ,f=;char ch=get…
Code: #include<bits/stdc++.h> #define maxn 500005 using namespace std; int n,Q,ty,lastans=0; int rt[maxn], tim[maxn], lp[maxn], tp[maxn]; void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r&q…
题解见大佬博客 我的丑陋代码: #include<cstdio> #include<cstring> #include<cstdlib> inline int read() { int x;char c; '); +c-'; return x; } #define MN 8000 #define MV 16000 #define ME 56000 #define INF 0x3FFFFFFF +]; ,T=MV+,h[MV+],en=,d[MV+],q[MV+],qn,…
我又来更博啦     2124: 等差子序列 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 941  Solved: 348[Submit][Status][Discuss] Description 给一个1到N的排列{Ai},询问是否存在1<=p1=3),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列. Input 输入的第一行包含一个整数T,表示组数.下接T组数据,每组第一行一个整数N,每组第二行为一个1到N的排列,数字两两之间用空格隔…
题目 给定两个序列a和b,每个序列中可能含有重复的数字. 一个配对(i,j)是一个好配对当从第一个序列中选出一个数ai,再从第二个序列中选出一个数bj且满足ai>bj. 给出两个序列,问存在多少个好配对. 题目链接: 好配对 有题目要求,知道题目的数据量比较大:a和b中分别最多有10^5种不同数字,每个数字最多有10^4个.因此,要求算法有O(nlogn)的时间复杂度.     一开始使用了两个map,map1为序列a中的数字以及对应的个数构成的数对:map2为对于序列a中的数字x,序列b中小于…
      问题描述:               后缀树(Suffix Tree)   参考资料: http://www.cppblog.com/yuyang7/archive/2009/03/29/78252.html http://blog.csdn.net/v_july_v/article/details/6897097 简介 后缀树是一种PAT树,它描述了给定字符串的所有后缀,许多重要的字符串操作都能够在后缀树上快速地实现. 定义 一个长度为n的字符串S,它的后缀树定义为一棵满足如下条…
题目链接:http://acm.swust.edu.cn/problem/code/745255/ Time limit(ms): 1000 Memory limit(kb): 65535   Description 以下方法称为最小代价的字母树:给定一正整数序列,例如:4,1,2,3,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所得到的和. 例如:((4+1)+ (2+3))=((5)+(5))=10.除去原数不4,1,2,3之外,其余都为中间结果,如5,5,10,将中间结果…
在计算机领域,Merkle树大多用来进行完整性验证处理.在处理完整性验证的应用场景中,特别是在分布式环境下进行这样的验证时,Merkle树会大大减少数据的传输量以及计算的复杂度. Merkle哈希树是一类基于哈希值的二叉树或多叉树,其叶子节点上的值通常为数据块的哈希值,而非叶子节点上的值是将该节点的所有子节点的组合结果的哈希值. 如下图所示为一个Merkle哈希树,节点A的值必须通过节点C.D上的值计算而得到.叶子节点C.D分别存储数据块001和002的哈希值,而非叶子节点A存储的是其子节点C.…
传送门 因为每一位\(\mod 3\)的值为\(1,2,1,2,...\),也就相当于\(1,-1,1,-1,...\) 所以当某个区间的\(1\)的个数为偶数的时候,一定是可行的,只要把这若干个\(1\)放在一起就可以了. 而当某个区间的\(1\)的个数为奇数的时候,那么最优的方式显然是\(1\)和\(-1\)两两配对,剩下\(3\)个\(1\),然后留下至少\(2\)个\(0\),将\(111\)拼成\(10101\)的形式. 注意到\(1\)的个数为\(1\)的时候显然不可行. 所以合法的…
[BZOJ5294][BJOI2018]二进制(线段树) 题面 BZOJ 洛谷 题解 二进制串在模\(3\)意义下,每一位代表的余数显然是\(121212\)这样子交替出现的. 其实换种方法看,就是\(1,-1,1,-1,...\) 如果询问一个二进制串能否被\(3\)整除,那么只需要考虑奇数位上的\(1\)的个数和偶数位上的\(1\)的个数就行了. 如果可以重排,我们来考虑如何分配. 首先对于一个长度为\(len\)的区间,模\(3\)余\(1\)的位有\([\frac{len+1}{2}]\…
Preface 可并堆,一个听起来很NB的数据结构,实际上比一般的堆就多了一个合并的操作. 考虑一般的堆合并时,当我们合并时只能暴力把一个堆里的元素一个一个插入另一个堆里,这样复杂度将达到\(\log(|A|)+\log(|B|)\),极限数据下显然是要T爆的. 所以我们考虑使用一种性价比最高的可并堆--左偏树,它的思想以及代码都挺简单而且效率也不错. 学习和参考自这里 What is Leftist Tree 左偏树,顾名思义就是像左偏的树,但是这样抽象的表述肯定是不符合我们学OI的人的背板子…
关于配对堆的一些小姿势: 1.配对堆是一颗多叉树. 2.包含优先队列的所有功能,可用于优化Dijkstra算法. 3.属于可并堆,因此对于集合合并维护最值的问题很实用. 4.速度快于一般的堆结构(左偏树,斜堆,随机堆……),具体时间复杂度: 合并(Merge):$O(1)$: 插入(Insert/Push):$O(1)$: 修改值(Change):$O(1) \sim O(\log n)$: 取出维护的最值(Top):$O(1)$: 弹出堆顶元素(Pop):$O(\log n)$: 我们依然拿洛…
转:http://blog.csdn.net/v_july_v/article/details/6897097 引言 常关注本blog的读者朋友想必看过此篇文章:从B树.B+树.B*树谈到R 树,这次,咱们来讲另外两种树:Tire树与后缀树.不过,在此之前,先来看两个问题.    第一个问题: 一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,请给出思想,给出时间复杂度分析. 之前在此文:海量数据处理面试题集锦与Bit-map详解中给出的参考答案:用trie树统计每个…
题意:给出一个长度为 n的数列 a和一个长度为 m 的数列 b,求 a有多少个长度为 m的连续子数列能与 b匹配.两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当且仅当它们的和不小于 h. 题解:先把b排序,要想能匹配,由hall定理,b的每个子集(大小为x)都至少有x条连向b,bi递增,和bi连的边也递增,那么当bi连边大于等于i时即可,所以当min(bi-i)>=0时满足条件 线性扫一遍即可,每个a二分b更新线段树即可 //#pragma GCC opt…
Description Solution 看到这种路径统计问题,一般就想到要用点分治去做. 对于每个重心\(u\),统计经过\(u\)的合法的路径之中的最大值. 第一类路径是从\(u\)出发的,直接逐个子树深搜统计就可以了.第二类路径是由两棵不同子树中的两条第一类路径拼接而成的. 如果仅仅是统计长度在\([l,r]\)之间的路径有多少条,经典的统计+容斥做法就可以解决.然而现在的问题比较复杂,一来不好容斥,二来两两路径配对需要有判定条件:两条路径的接口边颜色是否相同. 我们可以采用一种不需要容斥…
突然觉得堆优化$O(log_n)$的复杂度很优啊,然而第n次忘记了$Dijistra$怎么写QAQ发现之前都是用的手写堆,这次用一下$stl$ #include<bits/stdc++.h> #define LL long long using namespace std; int n, m; struct Node { int v, nex, w; Node(, , ) : v(v), nex(nex), w(w) { } } Edge[]; ], stot; void add(int u,…