bzoj 3697】的更多相关文章

[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3697 [算法] 首先 , 将黑色的边变成1 ,白色的边变成-1 那么 , 问题就转化为了有多少条路径满足 : 1. 路径长度为0 2. 路径中间存在一个点使得这个点可以将这条路径分成两段且长度为0 考虑我们已经处理完了前面的子树 , 对于当前子树中一点x , 深度为d , 显然 , 前面的子树中要有一个深度为-d的点y ,这条路径合法当且仅当x到分治重心的路径上有一点满足d[z]…
传送门 题意: 路径有$-1,1$两种权值,求有多少路径满足权值和为$0$且有一个点将路径分成权值和为$0$的两段 第四节课本来想去上化学,然后快上课了这道题还没调出来.....可恶我想上化学 昨天两节语文课潸然的李煜讲座也没去听呜呜听说今天的语文课还有什么文艺活动又错过了呜呜 还是有思路的 点分治,考虑经过$u$的路径 首先保证权值和为$0$,记录$c[i]$为当前权值和为$i$的路径有几条 怎么满足有一个点呢? $0+0=0$!!! 我们只要保证一段和$0$另一段自然也是$0$ 所以补充保存…
题目链接: TP 题解: 调了好久233. 大概想一想就是树分,然后考虑这样路径(u,v)的特征,以根节点(root)切开,u到root的阴阳差值,和v到root巧合互为相反数,然后考虑要有一个点可作为休息点,即u/v到root的路径中要有一点x与u/v到root的阴阳差值相同,然后维护一下就好. 注意的是阴阳差为0的特判……写挂了调好久,对拍也不好写,真是恶心. 代码: #define Troy 11/23 #define inf 0x7fffffff #include <bits/stdc+…
题目描述:这里 发现还是点对之间的问题,于是还是上点分 只不过是怎么做的问题 首先对每条边边权给成1和-1(即把原来边权为0的边边权改为-1),那么合法的路径总权值一定为0! 还是将路径分为经过当前根节点和不经过当前根节点的,对不经过当前点的递归处理 那么我们讨论经过当前根节点的路径算法即可 可以发现,如果一条路径经过当前根节点,那么当前根节点可以将这条路径分成两部分,且这两部分权值互为相反数! (这是很显然的,如果不互为相反数的话那么加起来肯定不是0啊) 接下来我们分析中转站的问题: 其实中转…
点分治,设当前处理的块的重心为rt,预处理出每个子树中f[v][0/1]表示组合出.没组合出一对值v的链数(从当前儿子出发的链),能组合出一对v值就是可以有一个休息点 然后对于rt,经过rt且合法的路径是两边拼起来至少有一个休息点的路径,每次假如新儿子都和之前的儿子组合一遍即可,注意f[0][0]实际上也是有休息点的,因为组合出0就是休息点,另外加一下 #include<iostream> #include<cstdio> using namespace std; const in…
题目大意: 从前有一棵无向树,树上边权均为$0$或$1$,有一个采药人,他认为如果一条路径上边权为$0$和$1$的边数量相等,那么这条路径阴阳平衡.他想寻找一条合法的采药路径,保证阴阳平衡.然后他发现采药很累,于是乎他需要保证这条路径上有一个中转站,路径两个端点到中转站的路径都需要阴阳平衡 $n \leqslant 10^{5}$,求合法路径数 把$0$边边权变成$-1$,易发现如果一条路径阴阳平衡,那么边权总和为$0$ 由于是树上路径的计数问题,考虑树分治,每次选中心作为根,设某点$x$到根的…
好久不做点分治的题了,正好在联赛之前抓紧复习一下. 先把边权为 $0$ 的置为 $-1$.定义几个状态:$f[dis][0/1],g[dis][0/1]$ 其中 $f$ 代表在当前遍历的子树内的答案. 其中 $f[dis][0]$ 表示到根节点距离为 $dis$,没有遇到平衡点的个数,$f[dis][1]$ 表示遇到平衡点的个数. 然后就把 $f$ 和 $g$ 用乘法原理乘一下就可以了. 注意要及时清空. #include <cstdio> #include <vector> #i…
点分治 Orz hzwer 倒是比较好想到点分治……然而在方案统计这里,我犯了两个错误…… 1.我比较傻逼的想的是:通过儿子来更新父亲,也就是统计以x为根的子树中xxxx的路径有多少条……这样转移. 然而这实在是太傻逼了,黄学长教做人:从父亲来更新儿子,走到一个节点直接更新路径的统计数,反正我们要的是[经过root的xx路径的数量] 所以可以一遍dfs直接搞出来…… 2.统计方案的方式也想错了……我只考虑了以root作为中转站的路径,然而经过root的路径中,并不只有这种路径是合法的……中转站在…
传送门 不是那么裸的点分治. $f[i][0/1]$表示当前节点的一个子树中总权值和为$i$,且是否存在一个前缀使得其前缀和为$i$ $g[i][0/1]$表示当前节点的已遍历过的子树,其余一样. 对于每个节点 $ans_{node}=g[0][0]∗f[0][0]+ \sum (g[−i][0]∗f[i][1]+g[−i][1]∗f[i][0]+g[−i][1]∗f[i][1])$ 另外,Race那道题选根的方案在这里好像不是很适用,容易出问题,还是换黄学长的比较好. //BZOJ 3697…
点分治: 点分治的题目基本一样,都是路径计数. 其复杂度的保证是依靠 $O(n)$ 找重心的,每一次至少将问题规模减小为原先的$1/2$. 找重心我喜欢$BFS$防止爆栈. int Root(int x){ dfsn[]=; q.push(x); fa[x]=; flag[x]=; while(!q.empty()){ int x=q.front(); q.pop(); dfsn[++dfsn[]]=x; for(int i=g[x];i;i=E[i].to) if(!v[p] && !f…