30%:暴力

40%:枚举L,R从L~n枚举,R每增大一个,更新需要的边(bfs实现)60%:枚举每条边,

计算每条边的贡献另外20%的数据:枚举每条边,计算每条边的贡献100%:对于每一条边统计

有多少个区间跨过这条边即可统计这一问题的对偶问题,有多少个区间没跨过会更方便使用启发式合并+

并查集统计子树内的,使用启发式合并+set统计子树外的

代码:

#include<cstdio>
#include<cstdlib>
#include<set>
#include<vector>
#include<iostream>
#define LL long long
#define int long long
using namespace std;
const int MAXN = 1e5 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, siz[MAXN], son[MAXN], dsu[MAXN], Son, vis[MAXN], ds[MAXN];
vector<int> v[MAXN];
set<int> s;
LL outt, inn, ans;
void dfs(int x, int _fa)
{
siz[x] = 1;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i]; if(to == _fa) continue;
dfs(to, x);
siz[x] += siz[to];
if(siz[to] > siz[son[x]]) son[x] = to;
}
}
LL calc(LL x) {
return x * (x - 1) / 2;
}
void Clear() {
s.clear();
outt = calc(N);
inn = 0;
s.insert(0);
s.insert(N + 1);
}
int find(int x)
{
return dsu[x] == x ? dsu[x] : dsu[x] = find(dsu[x]);
}
void solve(int x)
{
s.insert(x);
set<int>::iterator s1, s2, it;
s1 = s2 = it = s.find(x);
s1--; s2++;
outt -= calc((*s2) - (*s1) - 1);
outt += calc((*s2) - (*it) - 1) + calc((*it) - (*s1) - 1);
vis[x] = 1;
if(vis[x - 1]) {
int fx = find(x - 1), fy = find(x);
inn += ds[fx] * ds[fy];
dsu[fx] = fy;
ds[fy] += ds[fx];
}
if(vis[x + 1]) {
int fx = find(x + 1), fy = find(x);
inn += ds[fx] * ds[fy];
dsu[fx] = fy;
ds[fy] += ds[fx];
}
}
void Add(int x, int fa)
{
solve(x);
for(int i = 0; i < v[x].size(); i++)
{
int to = v[x][i];
if(to == fa || to == Son) continue;
Add(to, x);
}
}
void Delet(int x, int fa) {
vis[x] = 0; ds[x] = 1; dsu[x] = x;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if(to == fa) continue;
Delet(to, x);
}
}
void dfs2(int x, int fa, int opt)
{
for(int i = 0; i < v[x].size(); i++)
{
int to = v[x][i];
if(to == fa || (to == son[x])) continue;
dfs2(to, x, 0);
}
if(son[x]) dfs2(son[x], x, 1); Son = son[x];
Add(x, fa);
ans += calc(N) - inn - outt;
if(opt == 0) Delet(x, fa), Clear(), Son = 0;
}
signed main()
{
#ifdef yilnr
#else
freopen("treecnt.in","r",stdin);
freopen("treecnt.out","w",stdout);
#endif
N = read();
for(int i = 1; i <= N - 1; i++)
{
int x = read(), y = read();
v[x].push_back(y);
v[y].push_back(x);
}
for(int i = 1; i <= N; i++) dsu[i] = i,ds[i] = 1;
dfs(1,0);
Clear();
dfs2(1,0,0);
printf("%lld\n",ans);
return 0;
}
/*
4
1 4
1 3
2 4
*/

【csp模拟赛6】树上统计-启发式合并,线段树合并的更多相关文章

  1. 【CSP模拟赛】God knows (李超线段树)

    题面 CODE 稍微分析一下,发现把(i,pi)(i,p_i)(i,pi​)看做二维数点,就是求极长上升子序列的权值最小值. 直接李超线段树 #include <bits/stdc++.h> ...

  2. 5.20 省选模拟赛 T1 图 启发式合并 线段树合并 染色计数问题

    LINK:图 在说这道题之前吐槽一下今天的日子 520 = 1+1+4+514. /cy 这道题今天做的非常失败 一点分都没拿到手 关键是今天的T3 把我整个人给搞崩了. 先考虑 如果得到了这么一张图 ...

  3. HDU - 4358 Boring counting (树上启发式合并/线段树合并)

    题目链接 题意:统计树上每个结点中恰好出现了k次的颜色数. dsu on tree/线段树合并裸题. 启发式合并1:(748ms) #include<bits/stdc++.h> usin ...

  4. [XJOI NOI2015模拟题13] C 白黑树 【线段树合并】

    题目链接:XJOI - NOI2015-13 - C 题目分析 使用神奇的线段树合并在 O(nlogn) 的时间复杂度内解决这道题目. 对树上的每个点都建立一棵线段树,key是时间(即第几次操作),动 ...

  5. 启发式合并 splay合并 线段树合并基础

    Gold is everywhen! - somebody 启发式合并 将小的集合一个个插入到大的集合. 每次新集合大小至少比小集合大一倍,因此每个元素最多合并\(\log n\)次,总复杂度为\(n ...

  6. 启发式合并&线段树合并/分裂&treap合并&splay合并

    启发式合并 有\(n\)个集合,每次让你合并两个集合,或询问一个集合中是否存在某个元素. ​ 我们可以用平衡树/set维护集合. ​ 对于合并两个\(A,B\),如果\(|A|<|B|\),那么 ...

  7. [BZOJ2733][HNOI2010]永无乡 解题报告 启发式合并,线段树合并

    好久没更新博客了,前段时间一直都在考试,都没时间些,现在终于有点闲了(cai guai)... 写了一道题,[HNOI2012]永无乡,其实是一道板子题,我发现我写了好多板子题...还是太菜了... ...

  8. bzoj2733: [HNOI2012]永无乡(splay+启发式合并/线段树合并)

    这题之前写过线段树合并,今天复习Splay的时候想起这题,打算写一次Splay+启发式合并. 好爽!!! 写了长长的代码(其实也不长),只凭着下午的一点记忆(没背板子...),调了好久好久,过了样例, ...

  9. [NOIP10.6模拟赛]2.equation题解--DFS序+线段树

    题目链接: 咕 闲扯: 终于在集训中敲出正解(虽然与正解不完全相同),开心QAQ 首先比较巧,这题是\(Ebola\)出的一场模拟赛的一道题的树上强化版,当时还口胡出了那题的题解 然而考场上只得了86 ...

  10. 【CSP模拟赛】避难向导(倍增lca&树的直径)

    耐力OIer,一天7篇博客 题目描述 “特大新闻,特大新闻!全国爆发了一种极其可怕的病毒,已经开始在各个城市 中传播开来!全国陷入了巨大的危机!大量居民陷入恐慌,想要逃到其它城市以 避难!经调查显示, ...

随机推荐

  1. Hibernate一对多自关联、多对多关联

    今天分享hibernate框架的两个关联关系    多对多关系注意事项 一定要定义一个主控方 多对多删除 主控方直接删除 被控方先通过主控方解除多对多关系,再删除被控方 禁用级联删除 关联关系编辑,不 ...

  2. 深度剖析Kubernetes API Server三部曲 - part 1

    欢迎来到深入学习Kubernetes API Server的系列文章,在本系列文章中我们将深入的探究Kubernetes API Server的相关实现.如果你对Kubernetes 的内部实现机制比 ...

  3. 第八讲,TLS表(线程局部存储)

    一丶复习线程相关知识 首先讲解TLS的时候,需要复习线程相关知识,  (thread local storage ) 1.了解经典同步问题 首先我们先写一段C++代码,开辟两个线程去跑,看看会不会出现 ...

  4. (十三)Activitivi5之流程控制网关:并行

    一.概念 所谓排他网关 顾名思义 执行到该网关,会有多条线路同时并行执行,当都执行完才继续执行后面的: 二. 案例 此时当“学生请假”任务节点完成之后,如下图此时有两个任务,必须等到两个任务都完成才会 ...

  5. (二)Redis之Jedis概念和HelloWorld实现以及JedisPool的使用

    一.Jedis概念 实际开发中,我们需要用Redis的连接工具连接Redis然后操作Redis, 对于主流语言,Redis都提供了对应的客户端: 官网:https://redis.io/clients ...

  6. 编译openwrt backfire过程中出现的问题

    参考的步骤如链接: http://www.right.com.cn/forum/forum.php?mod=viewthread&tid=124604 在make menuconfig的时候出 ...

  7. Linux学习笔记:split切分文件并按规律命名及添加拓展名

    基础知识 功能:使用 shell 的 split 可以将一个大文件分割成很多个小文件,有时文件太大处理起来不方便就需要使用到了. 在默认情况下将按照每1000行切割成一个小文件. 语法: split ...

  8. css之弹性盒模型

    弹性盒子(Flexible Box/filebox)是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式.引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子 ...

  9. bootstrap 模态框在iphone微信内点击无效

    <a  data-toggle="modal" data-target="#wwww" href=""  οnclick=" ...

  10. Spark学习笔记2——RDD(上)

    目录 Spark学习笔记2--RDD(上) RDD是什么? 例子 创建 RDD 并行化方式 读取外部数据集方式 RDD 操作 转化操作 行动操作 惰性求值 Spark学习笔记2--RDD(上) 笔记摘 ...