数链剖分(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) ...
随机推荐
- 2017-2018-2 1723《程序设计与数据结构》第三周作业 & 实验一 总结
作业地址 第三周作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1667 提交情况如图: 实验一:https://edu.c ...
- 第二个Sprint冲刺第 八天(燃尽图)
因为今天停电了,所以我们也休息一天!
- cdq分治解决三维偏序
问题背景 在三维坐标系中有n个点,坐标为(xi,yi,zi). 定义一个点A比一个点B小,当且仅当xA<=xB,yA<=yB,zA<=zB.问对于每个点,有多少个点比它小.(n< ...
- [转帖]Vim编辑器使用方法详解
Vim编辑器使用方法详解 程序员小新人学习 2018-12-16 12:26:23 转载于https://www.cnblogs.com/libaoliang/articles/6961676.htm ...
- OneZero第二周第五次站立会议(2016.4.1)
会议时间:2016年4月1日 会议成员:冉华,张敏,夏一鸣.(王请假). 会议目的:汇报前一天工作,会议成员评论. 会议内容: 1.前端,由夏,张负责汇报,完成前端功能,待命. 2.数据逻辑控制,由王 ...
- springboot+dubbo+zookeeper微服务实践demo
微服务化越来越火,实际上是应互联网时代而生的,微服务化带来的不仅是性能上的提升,更带来了研发组织的更加便利,协作更加轻松,团队效能更高. 当然不能为了技术而技术,我们需要切合实际的对业务进行划分,降低 ...
- C# 登录窗口的设计技巧
记得很久之前要用C#做个需要登录的小东西,自己之前完全没有编写WinForm的经验,整个过程中,自己感觉应该怎么写就怎么写,时常导致许多逻辑性的错误,比如在做这个登录窗口的时候,应该实现的效果是,用户 ...
- Java之可变参数方法使用说明
代码: package test_demo; /* * 可变参数函数说明 * 传入指定数据类型的数组 * 优先匹配固定长度函数 * */ public class VarArgsDemo { // 可 ...
- 页面用一个遮罩层显示加载,加载完后隐藏该div
<div id="background" class="background" style="display: none; "> ...
- MySQL:日期类型
1. datetime(年月日时分秒) 格式:‘YYY-MM-DD HH:MM:SS’. 占用:8字节 范围:1000-01-01 00:00:00 到 9999-12-31 23:59:59. ti ...