【线段树 树链剖分 差分 经典技巧】loj#3046. 「ZJOI2019」语言【未完】
还是来致敬一下那过往吧
题目分析
先丢代码
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ;
const int maxNode = ; struct node
{
int top,son,fa,tot;
}a[maxn];
struct point
{
int u,v;
point(int a=, int b=):u(a),v(b) {}
};
struct tree
{
int ls,rs,cov,val;
}f[maxNode];
int n,m,tot;
long long ans,det;
int chain[maxn],chTot,rt[maxn];
int edgeTot,head[maxn],edges[maxm],nxt[maxm],dep[maxn];
std::vector<point> opt[maxn];
std::vector<int> inc[maxn],dec[maxn]; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void addedge(int u, int v)
{
edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void dfs1(int x, int fa)
{
dep[x] = dep[fa]+, a[x].tot = ;
a[x].top = a[x].son = -, a[x].fa = fa;
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i];
if (v==fa) continue;
dfs1(v, x), a[x].tot += a[v].tot;
if (a[x].son==-||a[a[x].son].tot < a[v].tot)
a[x].son = v;
}
}
void dfs2(int x, int top)
{
a[x].top = top, chain[x] = ++chTot;
if (a[x].son==-) return;
dfs2(a[x].son, top);
for (int i=head[x]; i!=-; i=nxt[i])
if (edges[i]!=a[x].fa&&edges[i]!=a[x].son)
dfs2(edges[i], edges[i]);
}
void splitChain(int id, int u, int v)
{
inc[u].push_back(id), inc[v].push_back(id);
while (a[u].top!=a[v].top)
{
if (dep[a[u].top] > dep[a[v].top]) std::swap(u, v);
opt[id].push_back(point(chain[a[v].top], chain[v]));
v = a[a[v].top].fa;
}
if (dep[u] > dep[v]) std::swap(u, v);
opt[id].push_back(point(chain[u], chain[v]));
dec[u].push_back(id), dec[a[u].fa].push_back(id);
}
void pushup(int rt, int len)
{
if (f[rt].cov) f[rt].val = len;
else f[rt].val = f[f[rt].ls].val+f[f[rt].rs].val;
}
void mergeSeg(int &u, int v, int l, int r)
{
if (!u||!v) u += v;
else{
int mid = (l+r)>>;
f[u].cov += f[v].cov;
mergeSeg(f[u].ls, f[v].ls, l, mid);
mergeSeg(f[u].rs, f[v].rs, mid+, r);
}
pushup(u, r-l+);
}
void update(int &rt, int L, int R, int l, int r, int c)
{
if (!rt) rt = ++tot;
if (L <= l&&r <= R) f[rt].cov += c, pushup(rt, r-l+);
else{
int mid = (l+r)>>;
if (L <= mid) update(f[rt].ls, L, R, l, mid, c);
if (R > mid) update(f[rt].rs, L, R, mid+, r, c);
}
pushup(rt, r-l+);
}
void delta(int x, int fa)
{
for (int i=head[x]; i!=-; i=nxt[i])
if (edges[i]!=fa) delta(edges[i], x);
for (int l=; l<inc[x].size(); l++)
for (int i=,mx=opt[inc[x][l]].size(); i<mx; i++)
update(rt[x], opt[inc[x][l]][i].u, opt[inc[x][l]][i].v, , n, );
for (int l=; l<dec[x].size(); l++)
for (int i=,mx=opt[dec[x][l]].size(); i<mx; i++)
update(rt[x], opt[dec[x][l]][i].u, opt[dec[x][l]][i].v, , n, -);
int val = f[rt[x]].val;
if (val) ans += val, ++det;
mergeSeg(rt[fa], rt[x], , n);
}
int main()
{
memset(head, -, sizeof head);
n = read(), m = read();
for (int i=; i<n; i++)
addedge(read(), read());
dfs1(, ), dfs2(, );
for (int i=; i<=m; i++)
splitChain(i, read(), read());
delta(, );
printf("%lld\n",(ans-det)/);
return ;
}
【线段树 树链剖分 差分 经典技巧】loj#3046. 「ZJOI2019」语言【未完】的更多相关文章
- bzoj5518 & loj3046 「ZJOI2019」语言 线段树合并+树链的并
题目传送门 https://loj.ac/problem/3046 题解 首先问题就是问有多少条路径是给定的几条路径中的一条的一个子段. 先考虑链的做法. 枚举右端点 \(i\),那么求出 \(j\) ...
- @loj - 3043@「ZJOI2019」线段树
目录 @description@ @solution@ @accepted code@ @details@ @description@ 九条可怜是一个喜欢数据结构的女孩子,在常见的数据结构中,可怜最喜 ...
- 【LOJ】#3043. 「ZJOI2019」线段树
LOJ#3043. 「ZJOI2019」线段树 计数转期望的一道好题-- 每个点设两个变量\(p,q\)表示这个点有\(p\)的概率有标记,有\(q\)的概率到祖先的路径上有个标记 被覆盖的点$0.5 ...
- LOJ #2359. 「NOIP2016」天天爱跑步(倍增+线段树合并)
题意 LOJ #2359. 「NOIP2016」天天爱跑步 题解 考虑把一个玩家的路径 \((x, y)\) 拆成两条,一条是 \(x\) 到 \(lca\) ( \(x, y\) 最近公共祖先) 的 ...
- Loj #2570. 「ZJOI2017」线段树
Loj #2570. 「ZJOI2017」线段树 题目描述 线段树是九条可怜很喜欢的一个数据结构,它拥有着简单的结构.优秀的复杂度与强大的功能,因此可怜曾经花了很长时间研究线段树的一些性质. 最近可怜 ...
- loj#2255. 「SNOI2017」炸弹 线段树优化建图,拓扑,缩点
loj#2255. 「SNOI2017」炸弹 线段树优化建图,拓扑,缩点 链接 loj 思路 用交错关系建出图来,发现可以直接缩点,拓扑统计. 完了吗,不,瓶颈在于边数太多了,线段树优化建图. 细节 ...
- 「ZJOI2019」线段树 解题报告
「ZJOI2019」线段树 听说有人喷这个题简单,然后我就跑去做,然后自闭感++,rp++(雾) 理性分析一波,可以发现最后形成的\(2^k\)个线段树,对应的操作的一个子集,按时间顺序作用到这颗线段 ...
- loj#2665. 「NOI2013」树的计数
目录 题目链接 题解 代码 题目链接 loj#2665. 「NOI2013」树的计数 题解 求树高的期望 对bfs序分层 考虑同时符合dfs和bfs序的树满足什么条件 第一个点要强制分层 对于bfs序 ...
- HDU 5452——Minimum Cut——————【树链剖分+差分前缀和】ACdream 1429——Diversion——————【树链剖分】
Minimum Cut Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 65535/102400 K (Java/Others)Tota ...
随机推荐
- redis之五大数据类型
redis之五大数据类型 redis redis的两种链接方式 简单链接 1234 import redisconn = redis.Redis(host='10.0.0.200',port=6379 ...
- ssrf漏洞分析
ssrf漏洞分析 关于ssrf 首先简单的说一下我理解的ssrf,大概就是服务器会响应用户的url请求,但是没有做好过滤和限制,导致可以攻击内网. ssrf常见漏洞代码 首先有三个常见的容易造成ssr ...
- Luogu P3166 [CQOI2014]数三角形 组合数学
好题鸭.. 不好直接求三角形个数,那就用全集-补集,转化为求三点共线的数量. 具体求法是求出水平共线数量与竖直共线数量和斜线共线数量. 用排列组合的知识可知为水平和竖直的为$C_n^3$与$C_m^ ...
- Codeforces Round #563 (Div. 2) C. Ehab and a Special Coloring Problem
链接:https://codeforces.com/contest/1174/problem/C 题意: You're given an integer nn. For every integer i ...
- 首次开发H5长图页总结
首次开发H5长图页总结. 资源统一加载 资源统一加载, 分开获取 定义资源标识符 在src/resources目录下 定义各个资源模块. 在Asset.js中获取定义好的所有模块, 循环出具体的文件路 ...
- Jquery树形控件 $.fn.zTree.init
https://www.cnblogs.com/jin-/p/4646202.html asp.net 树形控件 $.fn.zTree.init 在网页中通过jquery脚本来构筑树形控件将是一个不错 ...
- 微服务的.NET Core示例框架
eShopOnContainers 是一个基于微服务的.NET Core示例框架 https://www.cnblogs.com/fengqingyangNo1/p/9438428.html 找到一个 ...
- php时间戳存在8小时误差
当将PHP时间戳转化为正常的时间格式一般的操作方法如下: $mytime=time(); echo $mytime.'<br />'; echo date('Y-m-d H:i:s',$m ...
- 中介者模式和php实现
中介者模式: 中介者模式(Mediator Pattern)定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互.中介者模 ...
- 切记切记:Spring配置文件中,Component-scan无法扫描到的类中的自动装配对象无法被调用,报空指针错误。
Spring单例注入,单例对象可设置成Spring元件. 只有Spring的元件中@Autowired才有用,在普通类中@Autowired虽然不会编译报错,但运行时会报空指针错误.