博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P3285 松鼠的新家 (树链剖分)
阅读量:4570 次
发布时间:2019-06-08

本文共 2286 字,大约阅读时间需要 7 分钟。

题目描述

松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。

松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。

维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。

因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。

输入输出格式

输入格式:

第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。

输出格式: 

一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。

 

输入输出样例

输入样例#1: 
51 4 5 3 21 22 42 34 5
输出样例#1: 
12121

说明

2<= n <=300000

 

因为这个题,只要最后面查询,所以可以用树状数组的区间修改来做,所以,上代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll(x) (x*2)#define rr(x) (x*2+1)#define lol long long using namespace std;const int maxn=300008;lol read(){ char ch=getchar();lol f=1,w=0; while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){w=w*10+ch-'0';ch=getchar();} return f*w;}struct sj{ lol to; lol next;}a[maxn*2];lol head[maxn],size;lol vis[maxn],js[maxn],n;lol top[maxn],son[maxn],num[maxn];lol id[maxn],dep[maxn],fa[maxn];lol c[maxn],nat[maxn];void add(lol x,lol y){ a[++size].to=y; a[size].next=head[x]; head[x]=size;} void dfs(lol rt,lol pre,lol deep){ dep[rt]=deep; num[rt]=1; fa[rt]=pre; for(int i=head[rt];i;i=a[i].next) { lol tt=a[i].to; if(tt!=fa[rt]) { dfs(tt,rt,deep+1); num[rt]+=num[tt]; if(num[tt]>num[son[rt]]) son[rt]=tt; } }}int dfn; void dfs_find(lol rt,lol zu){ dfn++; top[rt]=zu; id[rt]=dfn; if(son[rt]!=-1) dfs_find(son[rt],zu); for(int i=head[rt];i;i=a[i].next) { lol tt=a[i].to; if(tt!=son[rt]&&tt!=fa[rt]) { dfs_find(tt,tt); } } return;} int lowbit(int x){ return x&(-x);}void insert(int x,int z){ for(int i=x;i<=n;i+=lowbit(i)) { if(i==0)break;c[i]+=z;}}int check(int x){ int sum=0; for(int i=x;i>=1;i-=lowbit(i)) { sum+=c[i]; } return sum;} void change(int s,int t) //change 还有一点小问题 没有剪掉起点{ while(top[s]!=top[t]) { if(dep[top[s]]
id[t]) swap(s,t); insert(id[s],1); insert(id[t]+1,-1); return;} int main(){ memset(son,-1,sizeof(son)); memset(top,-1,sizeof(top)); n=read(); for(int i=1;i<=n;i++) vis[i]=read(); for(int i=1;i

 

转载于:https://www.cnblogs.com/Kv-Stalin/p/8195630.html

你可能感兴趣的文章
CF277D Google Code Jam
查看>>
(七)unittest单元测试框架
查看>>
(八) 自动化测试的实例(以浏览器为例)
查看>>
js获取单选框和复选框的值并判断值存在后允许转跳
查看>>
任务一:零基础HTML编码
查看>>
C#类和结构以及堆和栈大烩菜(本来就迷,那就让暴风来的更猛烈吧!)
查看>>
94. Binary Tree Inorder Traversal
查看>>
MongoDB安装及多实例启动
查看>>
[css]我要用css画幅画(三)
查看>>
eletron打包
查看>>
numpy
查看>>
连接池
查看>>
使用易语言COM对象取文件版本
查看>>
2.16.10.init进程详解1
查看>>
centos7 install idea and x-windows
查看>>
Spring Boot + Spring Cloud 构建微服务系统(九):配置中心(Spring Cloud Config)
查看>>
【转】LINQ to SQL语句(1)之Where
查看>>
《基于MVC的javascript web富应用开发》中的一些函数
查看>>
0014---简单的计算
查看>>
自己写的文字轮播(简陋版)
查看>>