P3258 [JLOI2014]松鼠的新家

文章目录

    • 题意:
    • 题解:
      • 树上差分
      • 代码:
      • 树链剖分
      • 代码:

P3258 [JLOI2014]松鼠的新家

题意:

n个点,n-1条边,给出每个点的拜访顺序,问每个点经过几次(最后一次移动不算拜访)

题解:

题意明确后就很好做了,对于给定的x和y,我们只需要分别将x和y到lca(x,y)经过的点加一即可
但是这样直接做肯定不行
有两个方法:

  1. 树上差分
  2. 树链剖分

树上差分

参考题解
我们先考虑对于数组,我们指定连续一段加一
我们现在对a2到a6区间进行加一
现在处理差分数组,我们对a2加一,对a7减一
差分属猪的定义:a[i] = a[i-1] + 差分数组[i]
也就是我们并没有改变区间的值,而是改变的两个数之间的相对大小
在这里插入图片描述
对于树上差分:
父亲节点u = 其所有的子节点 + 他本身的差分数组
我们现在改变S到T边上所有点的值
我们对S的父亲节点减1,对T加1

//把s->t路径上所有点均加w,
chafen[t] += w;
chafen[s的父节点] -= w; 

当计算每个点具体值时:


for(遍历与 u 相连的每一个子节点 v){num[u] += num[v]; 
}  
num[u] += chafen[u];//加上差分数组 

在这里插入图片描述
在本题中结合lca即可

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;const int maxn = 300050;
const int maxm = maxn << 1;
int N, M;
int a[maxn], t1, t2;
int head[maxn], cnt;struct Edge{int u, v, next;
}edge[maxm];inline void addedge(int u, int v){edge[++cnt].u = u;edge[cnt].v = v;edge[cnt].next = head[u];head[u] = cnt;
}int fa[maxn][31], dep[maxn];void dfs(int u, int faa){fa[u][0] = faa, dep[u] = dep[faa] + 1;for(int i = 1; i <= 30; i++){fa[u][i] = fa[ fa[u][i - 1] ][i - 1];}for(int i = head[u]; i ; i = edge[i].next){int v = edge[i].v;if(v == faa)continue;dfs(v, u);}
} inline int lca(int x, int y){if(dep[x] < dep[y])swap(x,y);for(int i = 30; i >= 0; i--){if(dep[ fa[x][i] ] >= dep[y]) x = fa[x][i];}if(x == y)return x;for(int i = 30; i >= 0; i--){if(fa[x][i] != fa[y][i]){x = fa[x][i], y = fa[y][i];}}return fa[x][0];
}int num[maxn];int answer(int u, int faa){for(int i = head[u]; i ; i = edge[i].next){int v = edge[i].v;if(v == faa)continue;answer(v, u);num[u] += num[v];}
}
int main(){cin>>N;for(int i = 1; i <= N; i++){cin>> a[i];}for(int i = 1; i < N; i++){cin>> t1>> t2;addedge(t1, t2);addedge(t2, t1);}dfs(1, 0);for(int i = 1; i <= N - 1; i++){int u = a[i], v = a[i + 1];int t = lca(u, v);num[ fa[t][0] ]	-= 1;num[ t ] -= 1;num[ u ] += 1;num[ v ] += 1;}answer(1,0);for(int i = 2; i <= N; i++){num[a[i]]--;}for(int i = 1; i <= N; i++){cout<<num[i]<<endl;}
}

树链剖分

树链剖分就直接进行区间修改加一就行哈

代码:

这个代码我调了半个晚上,哭了哭了,终于调好了
在这里插入图片描述

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w;
}
const int maxn=1e6+9;
int a[maxn];
struct node{int u,v,next;
}edge[maxn];
int cnt=0;
int tot=0;
int n;
int head[maxn];
void add(int u,int v)
{edge[++cnt].v=v;edge[cnt].next=head[u];head[u]=cnt;
}
//---
int tr[maxn<<2],laz[maxn<<2];
inline void pushup(int rt)
{tr[rt]=tr[rt<<1]+tr[rt<<1|1];
}
inline void pushdown(int rt,int l,int r)
{int len=(r-l+1);laz[rt<<1]+=laz[rt];laz[rt<<1|1]+=laz[rt];tr[rt<<1]+=laz[rt]*(len-(len>>1));tr[rt<<1|1]+=laz[rt]*(len>>1);laz[rt]=0;
}
inline void build(int rt,int l,int r)
{if(l==r){tr[rt]=0;return ;}int mid=l+r>>1; build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);pushup(rt); 
}
inline int query(int rt,int l,int r,int ip)
{if(l==ip&&r==ip)return tr[rt];if(laz[rt])pushdown(rt,l,r);int mid=l+r>>1;int ress=0;if(ip<=mid)ress+=query(rt<<1,l,mid,ip);if(ip>mid)ress+=query(rt<<1|1,mid+1,r,ip);return ress;
}
inline void update(int rt,int l,int r,int L,int R,int k)
{if(L<=l&&r<=R){int len=(r-l+1);laz[rt]+=k;tr[rt]+=k*len;}else {if(laz[rt])pushdown(rt,l,r);int mid=l+r>>1;if(L<=mid)update(rt<<1,l,mid,L,R,k);if(R>mid)update(rt<<1|1,mid+1,r,L,R,k);pushup(rt);}
}
//---
int fa[maxn],dep[maxn],siz[maxn],id[maxn],top[maxn],son[maxn];
inline int updrange(int x,int y,int k)
{while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);update(1,1,n,id[top[x]],id[x],k);x=fa[top[x]];}if(dep[x]>dep[y])swap(x,y);update(1,1,n,id[x],id[y],k);
}
inline void dfs1(int x,int f,int deep)
{dep[x]=deep;fa[x]=f;siz[x]=1;int maxson=-1;for(int i=head[x];i;i=edge[i].next){int v=edge[i].v;if(v==f)continue;dfs1(v,x,deep+1);siz[x]+=siz[v];if(siz[v]>maxson){son[x]=v;maxson=siz[v];}}
}
inline void dfs2(int x,int topf)
{id[x]=++tot;top[x]=topf;if(!son[x])return ;dfs2(son[x],topf);for(int i=head[x];i;i=edge[i].next){int v=edge[i].v;if(v==fa[x]||v==son[x])continue;dfs2(v,v);}
}
void print()
{for(int i=1;i<=n;i++){printf("%d\n",query(1,1,n,id[i]));//cout<<<<endl;}
//	printf("----\n");
}
int main()
{cin>>n;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<n;i++){int x,y;cin>>x>>y;add(x,y);add(y,x);}dfs1(a[n],0,1);dfs2(a[n],a[n]);build(1,1,n);updrange(a[1],a[1],1);//print();for(int i=1;i<n;i++){updrange(a[i],a[i+1],1);updrange(a[i],a[i],-1);//	print();}updrange(a[n],a[n],-1);print();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318211.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[SOCI2005]最大子矩阵(DP) + [JXOI2018]守卫(DP) + [CQOI2016]手机号码(数位DP)[各种DP专练]

DP专练博客 DP专练T1&#xff1a;最大子矩阵题目题解代码实现T2&#xff1a;守卫题目题解代码实现T3&#xff1a;手机号码题目题解代码实现T1&#xff1a;最大子矩阵 题目 这里有一个n*m的矩阵&#xff0c;请你选出其中k个子矩阵&#xff0c;使得这个k个子矩阵分值之和最大。…

IdentityServer4-EF动态配置Client和对Claims授权(二)

本节介绍Client的ClientCredentials客户端模式&#xff0c;先看下画的草图&#xff1a;一、在Server上添加动态新增Client的API 接口。为了方便测试&#xff0c;在Server服务端中先添加swagger&#xff0c;添加流程可参考&#xff1a;https://www.cnblogs.com/suxinlcq/p/67575…

P3178 [HAOI2015]树上操作

P3178 [HAOI2015]树上操作 题意&#xff1a; 题解&#xff1a; 这已经是很裸的树链剖分了。。。 直接套模板 代码&#xff1a; #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespac…

dotnet core开源博客系统XBlog介绍

XBlog是dotnet core平台下的个人博客开源系统&#xff0c;它只需要通过Copy的方式即可以部署到Linux和windows系统中&#xff1b;如果你有安全证书那只需要简单配置一下即可提供安全的Https服务。接下来主要介绍XBlog功能、部署和基础设置。技术要点基于dotnet core平台&#x…

【莫队/树上莫队/回滚莫队】原理详解及例题:小B的询问(普通莫队),Count on a tree II(树上莫队),kangaroos(回滚莫队)

文章目录问题引入介绍莫队算法及其实现过程时间复杂度莫队算法适用范围莫队奇偶优化普通莫队&#xff1a;小B的询问树上莫队&#xff1a;SP10707 COT2 - Count on a tree II回滚莫队&#xff1a;[PA2011]Kangaroosupd&#xff1a;2021-08-11&#xff1a;重新对博客进行了外观美…

微软 2018 开源大事记

从微软公开宣布 "Microsoft love linux" 那一刻起&#xff0c;过去的几年里&#xff0c;微软积极拥抱开源的举动我们有目共睹&#xff0c;即便有过"Linux is a cancer"这种真香警告的 flag&#xff0c;但不得不承认的是&#xff0c;微软一系列“拥抱开源”…

模板:二叉搜索树平衡树

文章目录前言二叉搜索树代码treap代码splay开点旋转splay插入查找第k大元素查找给定元素的排名前驱&后继删除完整代码练习总结前言 终于开始学这个东西了 看了好几篇博客才找到一篇可读的qwq 我曾经还以为线段树码量大…我真傻&#xff0c;真的 所谓平衡树&#xff0c;就是…

P2486 [SDOI2011]染色

P2486 [SDOI2011]染色 题意&#xff1a; 题解&#xff1a; 与一般的树链剖分相比&#xff0c;不同点在于查询的不是路径上颜色的数量而是颜色段的数量 对于两个颜色段&#xff0c;112和221&#xff0c;两个颜色段数量都是2 如果合在一起颜色段的数量就是3&#xff0c;因为左边…

牛客网CSP-S提高组赛前集训营1题解(仓鼠的石子游戏 [博弈论] + 乃爱与城市的拥挤程度 [树上DP] + 小w的魔术扑克[dfs + 离线])

文章目录T1&#xff1a;仓鼠的石子游戏题目题解代码实现T2&#xff1a;乃爱与城市拥挤程度题目题解代码实现T3&#xff1a;小w的魔术扑克题目题解代码实现T1&#xff1a;仓鼠的石子游戏 题目 仓鼠和兔子被禁止玩电脑&#xff0c;无聊的他们跑到一块空地上&#xff0c;空地上有…

使用PerfView监测.NET程序性能(二):Perfview的使用

在上一篇博客使用PerfView监测.NET程序性能&#xff08;一&#xff09;&#xff1a;Event Trace for Windows 中&#xff0c;我们了解了对Windows及应用程序进行性能分析的基础&#xff1a;Event Trace for Windows (ETW)。现在来看看基于ETW的性能分析工具——Perfview.exePer…

学习有向图和无向图的强连通分量(基本概念+割点+点双联通分量+桥+边双连通分量+全套模板【Tarjan】)

最近总是考到Tarjan&#xff0c;让我措手不及基本概念割点以及点双连通分量Tarjan法求割点推导过程代码实现Tarjan法求点双连通分量推导过程代码实现有向图的Tarjan缩点桥与边双连通分量Tarjan法求桥理论推导代码实现Tarjan法求边双连通分量理论推导代码实现前言&#xff1a;有…

.NET Core下的Spring Cloud——前言和概述

前言前几年一直在写类似dubbo&#xff0c;Spring Cloud的微服务框架辗辗转转重复了多次&#xff0c;也重构推翻了很多次&#xff0c;其中诞生了“Rabbit.Rpc”,”Go”,”RabbitCloud”等开源项目。其中不乏他人对这些项目的完善。很高兴自己的开源项目能够给他人提供思路和复用…

CF785E Anton and Permutation

CF785E Anton and Permutation 题意&#xff1a; 对于一个长度为 n 的序列进行 k 次操作&#xff0c;每次操作都是交换序列中的某两个数。对于每一个操作&#xff0c;回答当前序列中有多少个逆序对。 1<n<200000 1<q<50000 题解&#xff1a; 动态逆序对&#x…

[ NOIP提高组 2016]愤怒的小鸟(暴搜 + 状压DP)// [SNOI2017]一个简单的询问(莫队)

一次性写两道题T1&#xff1a;一个简单的询问题目题解代码实现T2&#xff1a;愤怒的小鸟题目暴搜题解暴搜代码实现状压DP题解状压DP代码实现T1&#xff1a;一个简单的询问 题目 给你一个长度为 N 的序列 ai ,1≤i≤N&#xff0c;和 q 组询问&#xff0c;每组询问读入 l1,r1,l…

微软发布新的 Azure Pipelines 功能和集成

在最近举行的Connect()大会上&#xff0c;微软发布了几项新功能以及与 Azure Pipelines 的集成&#xff0c;包括 Visual Studio Code 的 Azure Pipelines 扩展、GitHub 版本管理、对 IoT 项目的支持以及 ServiceNow 集成。自从 9 月份推出 Azure Pipelines 以来&#xff0c;这种…

年末展望:Oracle 对 JDK收费和.NET Core 给我们的机遇

2018年就结束了&#xff0c;马上就要迎来2019年&#xff0c;这一年很不平凡&#xff0c;中美贸易战还在继续&#xff0c;IT互联网发生急剧变化&#xff0c;大量互联网公司开始裁员&#xff0c;微软的市值在不断上升 &#xff0c;在互联网公司的市值下跌过程中爬到了第一的位置&…

等比数列三角形 (数论 + 黄金分割点)+ JOISC 2016 Day3 T3 「电报」(基环树 + 拓扑排序)

文章目录T1&#xff1a;等比数列三角形题目题解代码实现T2&#xff1a;电报题目题解代码实现T1&#xff1a;等比数列三角形 题目 求三边都是 ≤n 的整数&#xff0c;且成等比数列的三角形个数 注意三角形面积不能为 0 注意 oeis 中未收录此数列&#xff0c;所以并不需要去搜了…

使用PerfView监测.NET程序性能(三):分组

在上一篇博客使用PerfView监测.NET程序性能&#xff08;二&#xff09;&#xff1a;Perfview的使用中&#xff0c;我们通过Perfview帮助文件中自带的代码来简单使用了Perfview&#xff0c;了解了基本操作。现在来看看Perfview中的分组操作&#xff08;Grouping&#xff09;。分…

【做题记录】构造题

CF468C Hack it! 题意&#xff1a; 令 \(F(x)\) 表示 \(x\) 的各个位上的数字之和&#xff0c;如 \(F(1234)123410\) 。 给定 \(a(a\le 10^{18})\) &#xff0c;请求出任意一组 \(l,r(l,r\le 10^{200})\) &#xff0c;要求满足&#xff1a; \[\sum_{il}^{r}F(i)\pmod{a}0 \]输出…

Star Way To Heaven (prim最小生成树) // [ NOIP提高组 2014]飞扬的小鸟(DP)

文章目录T1&#xff1a;Star Way To Heaven题目题解代码实现T2&#xff1a;飞扬的小鸟题目题解代码实现T1&#xff1a;Star Way To Heaven 题目 小 w 伤心的走上了 Star way to heaven。 到天堂的道路是一个笛卡尔坐标系上一个 n*m 的长方形通道 顶点在 (0,0) 和 (n,m) 。 小…