数链剖分(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) ...
随机推荐
- 2-Sixteenth Scrum Meeting-20151216
任务安排 成员 今日完成 明日任务 闫昊 写完学习进度记录的数据库操作 写完学习进度记录的数据库操作 唐彬 编写与服务器交互的代码 编写与服务器交互的代码 史烨轩 获取视频url 余帆 本地 ...
- js分页实例
js分页实例 案例1 1.js_pageusers.html <!DOCTYPE html> <html> <head> <title>js_pageu ...
- (Alpha)Let's-Chronos分数分配规则
Requirement: 每个团队开一个讨论会,协商讨论团队贡献分的分配方式.每个团队的团队贡献分为50分/人.每个人分数不能相同,请详细说明分数的分配规则. 为了完成此次的团队贡献分的分配任务,我们 ...
- 关于“代码规范”,“Review”和“Check list”
关于“代码规范”,“Review”和“Check list”,就我个人理解,这三者相辅相成.代码规范是在编程时就该注意的,为Review减轻负担.而要进行Review,又需要一个Check list作 ...
- mybatis之接口方法多参数的三种实现方式
关键代码举例: DaoMapper.xml <!-- 传入多个参数时,自动转换为map形式 --> <insert id="insertByColumns" us ...
- css命名管理混乱?不妨试试BEM
css的缺陷 我们知道,css使用中一个比较令人烦恼的问题,就是css没有作用域可言,我们写了一个组件或者模块之后,往往希望它们可以四处复用,但是由于css没有作用域,我们给样式命名的时候都会非常小心 ...
- java 23种设计模式 深入浅出
以下内容只作为对自己对知识进行总结,如有引用他人文章会在文段末尾表明出处: Java的23种设计模式 23种设计模式总共可以分为三大类,进行不定期更新总结,将逐步展开介绍自己对设计模式的理解,多多指教 ...
- #35 string(缩点+动态规划)
容易发现有了交换相邻字符的操作后,只要字符串所含有的字符种类和数量相同其就是等价的.这样的状态只有n^3级别,将其抽象成点子串变换抽象成边后就是求最长路径了,缩点dp解决. 码量巨大,不是很明白要怎样 ...
- Fantastic Graph 2018 沈阳赛区网络预赛 F题
题意: 二分图 有k条边,我们去选择其中的几条 每选中一条那么此条边的u 和 v的度数就+1,最后使得所有点的度数都在[l, r]这个区间内 , 这就相当于 边流入1,流出1,最后使流量平衡 解析: ...
- 洛谷P4234 最小差值生成树(LCT,生成树)
洛谷题目传送门 和魔法森林有点像,都是动态维护最小生成树(可参考一下Blog的LCT总结相关部分) 至于从小到大还是从大到小当然无所谓啦,我是从小到大排序,每次枚举边,还没连通就连,已连通就替换环上最 ...