51nod 1681 公共祖先 | 树状数组】的更多相关文章

51nod 1681 公共祖先 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另一个未知的平行宇宙,这n人的祖辈关系仍然是树形结构,但他们相互之间的关系却完全不同了,原来的祖先可能变成了后代,后代变成的同辈-- 两个人的亲密度定义为在这两个平行宇宙有多少人一直是他们的公共祖先. 整个家族的亲密度定义为任意两个人亲密度的总和. Input 第一行一个数n(1<=n<=100000) 接下来n-1行每行两个数x,y表示在第一个平行宇宙x是y的父亲. 接下…
[51nod 1681]公共祖先(dfs序+线段树合并) 题面 给出两棵n(n<=100000)个点的树,对于所有点对求它们在两棵树中公共的公共祖先数量之和. 如图,对于点对(2,4),它们在第一棵树里的公共祖先为{1,3,5},在第二棵树里的公共祖先为{1},因此公共的公共祖先数量为2 把所有点对的这个数量加起来,就得到了最终答案 分析 \(O(n^3)\)的暴力不讲了,先考虑\(O(n^2)\)的做法 枚举点对复杂度太高,不可行.我们考虑每个节点x作为公共的公共祖先的次数.设树A上的节点x,…
题意: 给出一个长度为\(n\)的数列\(A_i\),定义\(f(k)\)为所有长度大于等于\(k\)的子区间中前\(k\)大数之和的和. 求\(\sum_{k=1}^{n}f(k) \; mod \; 10^9+7\). 分析: 从某个长度为\(k\)的子区间对答案的贡献来看: 它的长度大于等于\(k\),所以区间中每个都加到答案中一次. 它的长度还大于等于\(k-1\),区间中前\(k-1\)大的数加到答案中一次. -- 以此类推. 对于每个数\(A_i\):如果这个区间中有\(x\)个小于…
题目链接 最大距离 其实主流解法应该是单调栈……我用了树状数组. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) ; struct node{ int x, y; friend bool operator < (const node &a, const node &b){ return a.x == b.x ? a.y &…
裸题,树状数组区间修改+单点查询.当然要稍微讨论一下链的左右端点是否修改的情况咯. #include<cstdio> #include<algorithm> #include<cmath> using namespace std; #define N 300001 int en,v[N<<1],first[N],next[N<<1],n; void AddEdge(const int &U,const int &V) { v[++…
1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另一个未知的平行宇宙,这n人的祖辈关系仍然是树形结构,但他们相互之间的关系却完全不同了,原来的祖先可能变成了后代,后代变成的同辈…… 两个人的亲密度定义为在这两个平行宇宙有多少人一直是他们的公共祖先. 整个家族的亲密度定义为任意两个人亲密度的总和. Input 第一行一个数n(1<=n<=10000…
51nod 1290 Counting Diff Pairs | 莫队 树状数组 题面 一个长度为N的正整数数组A,给出一个数K以及Q个查询,每个查询包含2个数l和r,对于每个查询输出从A[i]到A[j]中,有多少对数,abs(A[i] - A[j]) <= K(abs表示绝对值). 题解 莫队!//其实我就是搜索"51nod + 莫队"找到的这道题-- 七级算法题! 一道320分! 你值得拥有! 题解就是--用个普通的莫队,加上树状数组来统计符合条件的数个数,就好啦. 当增加/…
http://www.51nod.com/contest/problem.html#!problemId=1685 这是这次BSG白山极客挑战赛的E题. 这题可以二分答案t. 关键在于,对于一个t,如何判断它是否能成为第k大. 将序列中大于t的置为1,小于t的置为-1,等于t的置为0.那么区间中位数大于t的和就大于0,小于t的就小于0.于是就是判断区间和大于0的个数是否小于等于k. 维护前缀和sum(i),然后统计之前sum(j)小于sum(i)的有多少个,就是以i为右值的区间和大于0的个数.于…
公共子序列 题目链接:https://cometoj.com/contest/39/problem/E?problem_id=1585 数据范围:略. 题解: 首先可以考虑知道了$1$的个数和$3$的个数,怎么求? 其实就是从开始找$x$个$1$,从结尾找$z$个$3$,然后两个序列中间$2$的个数的较小值. 然后按照官方题解那样推式子,发现可以用树状数组维护. 代码: #include <bits/stdc++.h> #define N 5000010 using namespace std…
题目链接:子段求和 题意:n个数字序列,m次询问,每次询问从第p个开始L长度序列的子段和为多少. 题解:线段树区间求和 | 树状数组区间求和 线段树: #include <cstdio> #define LC(a) ((a<<1)) #define RC(a) ((a<<1)+1) #define MID(a,b) ((a+b)>>1) using namespace std; typedef long long ll; ; ll ans=; struct…