数链剖分(Tree)
题目链接:https://cn.vjudge.net/contest/279350#problem/D
题目大意:操作,单点查询,区间取反,询问区间最大值。
AC代码:
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
#include<stdio.h>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
# define lson l,m,rt<<
# define rson m+,r,rt<<|
const int maxn = 3e5+;
int sto[maxn],head[maxn],edgnum,dfsnum,depth[maxn];
int son[maxn],father[maxn],Size[maxn],ord[maxn],cost[maxn],top[maxn];
int maxtree[maxn<<],mintree[maxn<<],maxx,lazy[maxn<<];
struct node
{
int fr;
int to;
int nex;
int cost;
} edge[maxn],po[maxn];
void addedge(int fr,int to)
{
edge[edgnum].fr=fr;
edge[edgnum].to=to;
edge[edgnum].nex=head[fr];
head[fr]=edgnum++;
}
void dfs1(int fr,int rt,int dep)
{
father[fr]=rt;
Size[fr]=;
son[fr]=-;
depth[fr]=dep;
for(int i=head[fr]; i!=-; i=edge[i].nex)
{
int to=edge[i].to;
if(to==rt)
continue;
dfs1(to,fr,dep+);
Size[fr]+=Size[to];
if(son[to]==-||(Size[son[fr]]<Size[to]))
{
son[fr]=to;
}
}
}
void dfs2(int fr,int rt)
{
ord[fr]=++dfsnum;
cost[ord[fr]]=sto[fr];
top[fr]=rt;
if(son[fr]!=-)
dfs2(son[fr],rt);
for(int i=head[fr]; i!=-; i=edge[i].nex)
{
int u=edge[i].to;
if(son[fr]!=u&&father[fr]!=u)
{
dfs2(u,u);
}
}
}
void up(int rt)
{
maxtree[rt]=max(maxtree[rt<<],maxtree[rt<<|]);
mintree[rt]=min(mintree[rt<<],mintree[rt<<|]);
}
void buildtree(int l,int r,int rt)
{
if(l==r)
{
maxtree[rt]=sto[l];
mintree[rt]=sto[l];
lazy[rt]++;
return ;
}
int m=(l+r)>>;
buildtree(lson);
buildtree(rson);
up(rt);
}
void change(int rt)
{
int tmp=mintree[rt];
mintree[rt]=-maxtree[rt];
maxtree[rt]=-tmp;
}
void down(int rt)
{
if(!lazy[rt])
return ;
lazy[rt<<]^=;
lazy[rt<<|]^=;
change(rt<<);
change(rt<<|);
lazy[rt]^=;
}
void query(int l,int r,int rt,int L,int R)
{
if(L<=l&&R>=r)
{
maxx=max(maxx,maxtree[rt]);
return ;
}
down(rt);
int m=(l+r)>>;
if(L<=m)
query(lson,L,R);
if(R>m)
query(rson,L,R);
up(rt);
}
void update1(int l,int r,int rt,int pos,int p)
{
if(l==r)
{
maxtree[rt]=p;
mintree[rt]=p;
return ;
}
down(rt);
int m=(l+r)>>;
if(pos<=m)
update1(lson,pos,p);
if(pos>m)
update1(rson,pos,p);
up(rt);
}
void update2(int l,int r,int rt,int L,int R)
{
if(L<=l&&R>=r)
{
change(rt);
lazy[rt]^=;
return ;
}
down(rt);
int m=(l+r)>>;
if(L<=m)
update2(lson,L,R);
if(R>m)
update2(rson,L,R);
up(rt);
}
void Query(int n,int x,int y)
{
maxx=-inf;
int tx=top[x],ty=top[y];
while(tx!=ty)
{
if(depth[tx]<depth[ty])
{
swap(tx,ty);
swap(x,y);
}
query(,n,,ord[tx],ord[x]);
x=father[tx],tx=top[x];
}
if(depth[x]<depth[y])
{
swap(x,y);
}
query(,n,,ord[y]+,ord[x]);
}
void Update(int n,int x,int y)
{
int tx=top[x],ty=top[y];
while(tx!=ty)
{
if(depth[tx]<depth[ty])
{
swap(tx,ty);
swap(x,y);
}
update2(,n,,ord[tx],ord[x]);
x=father[tx],tx=top[x];
}
if(depth[x]<depth[y])
{
swap(x,y);
}
update2(,n,,ord[y]+,ord[x]);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
dfsnum=edgnum=;
int n,q,s;
scanf("%d",&n);
int t1,t2,t3;
memset(maxtree,,sizeof(maxtree));
memset(mintree,,sizeof(mintree));
memset(lazy,,sizeof(lazy));
memset(head,-,sizeof(head));
for(int i=; i<=n-; i++)
{
scanf("%d %d %d",&t1,&t2,&t3);
addedge(t1,t2);
addedge(t2,t1);
po[i].fr=t1;
po[i].to=t2;
po[i].cost=t3;
}
dfs1(,-,);
dfs2(,);
for(int i=; i<=n-; i++)
{
t1=depth[po[i].fr];
t2=depth[po[i].to];
if(t1>t2)
{
swap(po[i].fr,po[i].to);
}
update1(,n,,ord[po[i].to],po[i].cost);
}
char str[];
while(~scanf("%s",str))
{
if(str[]=='D')
break;
else if(str[]=='Q')
{
scanf("%d %d",&t1,&t2);
Query(n,t1,t2);
printf("%d\n",maxx);
}
else if(str[]=='C')
{
scanf("%d %d",&t1,&t2);
update1(,n,,ord[po[t1].to],t2);
}
else if(str[]=='N')
{
scanf("%d %d",&t1,&t2);
Update(n,t1,t2);
}
}
}
return ;
}
数链剖分(Tree)的更多相关文章
- G - Game HDU - 5242 (数链剖分)
题目链接: G - Game HDU - 5242 题目大意:首先是T组测试样例,给出一颗以1节点为根的树,每个节点有各自的价值,有m次从根节点出发向下走到叶子节点的机会,每次会得到所有经过节点的权值 ...
- 线段树&数链剖分
傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...
- 数链剖分(Aragorn's Story )
题目链接:https://vjudge.net/contest/279350#problem/A 题目大意:n个点,m条边,然后q次询问,因为在树上,两个点能确定一条直线,我们可以对这条直线上的所有值 ...
- 数链剖分(Housewife Wind )
题目链接:https://vjudge.net/contest/279350#problem/B 题目大意:给你n,q,s.n指的是有n个点,q代表有q次询问,s代表的是起点.然后接下来会有n-1条 ...
- 数链剖分(树的统计Count )
题目链接:https://cn.vjudge.net/contest/279350#problem/C 具体思路:单点更新,区间查询,查询的时候有两种操作,查询区间最大值和区间和. 注意点:在查询的时 ...
- POJ 3237 Tree (树链剖分)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 2825 Accepted: 769 Description ...
- 浅谈树链剖分(C++、算法、树结构)
关于数链剖分我在网上看到的有几个比较好的讲解,本篇主要是对AC代码的注释(感谢各位witer的提供) 这是讲解 http://www.cnblogs.com/kuangbin/archive/2013 ...
- 1036: [ZJOI2008]树的统计Count (树链剖分)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3401 Solved: 1418[Submit] ...
- HDU 3966 Aragorn's Story (树链剖分+树状数组)
Aragorn's Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- CSAPP lab2 二进制拆弹 binary bombs phase_2
给出对应于7个阶段的7篇博客 phase_1 https://www.cnblogs.com/wkfvawl/p/10632044.htmlphase_2 https://www.cnblogs. ...
- 团队作业week9
1. Bug bash ▪ How many bugs is found in your bug bash? 2. Write a blog to talk about your scenario t ...
- MFC Cstring转化为string
Cstring m_filePath; string sname( CW2A( m_filePath.GetString())); http://blog.sina.com.cn/s/blog_530 ...
- docker简易实践
docker简易实践 实验环境 操作系统:deepin 15.4 安装步骤 1.安装docker sudo apt-get install docker.io 2.启动docker服务 sudo se ...
- vs2013安装过程及使用心得
进入http://www.itellyou.cn/ 方法/步骤 1 1:点击中文简体 2:钩出前面的空格 3:点击详细信息 4:复制到网页进行搜索迅雷下载 等待下载完成之后,双击文件 我们双击文件 ...
- windows 服务实现定时任务调度(Quartz.Net)
我们通常在一些情况下需要软件具有一个自动执行某些任务的功能,但是又不希望直接启动软件,或者每次都要手动的来启动软件,这时我们可可以考虑到windows服务了. 首先创建一个windows服务项目(详细 ...
- Linux基础二(挂载、关机重启与系统等级)
一.Linux 基础之挂载 1. 挂载和查询 1.1 挂载 什么叫挂载?装系统的时候要给硬盘分区,在 Windows 中要分 C 盘 D 盘 DEF 盘,这个操作我们叫做分配盘符,分配盘符之后我们就可 ...
- HDU 2030 汉字统计
http://acm.hdu.edu.cn/showproblem.php?pid=2030 Problem Description 统计给定文本文件中汉字的个数. Input 输入文件首先包含一 ...
- RDM 使用与破解
RDM 的下载地址 https://cdn.devolutions.net/download/Setup.RemoteDesktopManager.13.6.2.0.msi#_ga=2.2471513 ...
- iOS程序执行顺序 AppDelegate及 UIViewController 的生命周期
iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 iOS应用程序的状态切换很重要,而UIViewControler对于iOS这种MVC模式来说尤为重要 ...