博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ - 3237 Tree (树链剖分+线段树)
阅读量:4505 次
发布时间:2019-06-08

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

题意:也是树链剖分的裸题,支持三种操作:1.修改一条边的权值;2.将点u,v路径上的边都取相反数;3.查询u,v路径上边的最大值。

老方法,用边的后继点表示边。这样的做法需要注意在查询和修改时,当两点回到一条链上之后,需要操作的区间不再是id[u]到id[v],而是id[son[u]]到id[v]。

线段树中需要同时维护区间最小值和最大值,二者取相反数后会变成对方。

#include
#include
#include
#include
using namespace std;typedef long long LL;const int maxn =1e4+5;const int INF = 0x3f3f3f3f;struct Edge{ int to,next;}E[2*maxn];int n,head[maxn],tot;int idx,size[maxn],fa[maxn],son[maxn],dep[maxn],top[maxn],id[maxn];int edge[maxn][3];void init(){ idx=tot=0; memset(head,-1,sizeof(head)); dep[1]=0,fa[1]=1,size[0]=0; memset(son,0,sizeof(son));}void AddEdge(int u,int v){ E[tot] = (Edge){v,head[u]}; head[u]=tot++;}void dfs1(int u){ size[u]=1; for(int i=head[u];~i;i=E[i].next){ int v=E[i].to; if(v!=fa[u]){ fa[v]=u; dep[v]=dep[u]+1; dfs1(v); size[u]+=size[v]; if(size[son[u]]
>1; build(Lson); build(Rson); pushup(rt);}void update1(int p,int v,int l=1,int r=n,int rt=1){ if(l==r){ tree[rt].mx = tree[rt].mn = v; tree[rt].add = 0; return; } pushdown(l,r,rt); int m = (l+r)>>1; if(p<=m) update1(p,v,Lson); else update1(p,v,Rson); pushup(rt);}void update2(int L,int R,int l=1,int r=n,int rt=1){ if(L<=l && R>=r){ tree[rt].add ^=1; solve(tree[rt].mx,tree[rt].mn); return; } pushdown(l,r,rt); int m = (l+r)>>1; if(L<=m) update2(L,R,Lson); if(R>m) update2(L,R,Rson); pushup(rt);}int query(int L,int R,int l=1,int r=n,int rt=1){ if(L<=l && R>=r) return tree[rt].mx; pushdown(l,r,rt); int m = (l+r)>>1; int ans = -INF; if(L<=m) ans = max(ans,query(L,R,Lson)); if(R>m) ans = max(ans,query(L,R,Rson)); pushup(rt); return ans;}//树剖int find(int u,int v){ int ans= -INF; while(top[u]!=top[v]){ if(dep[top[u]]
dep[v]) swap(u,v); return max(ans,query(id[son[u]],id[v],1,n,1)); }void reverse(int u,int v){ while(top[u]!=top[v]){ if(dep[top[u]]
dep[v]) swap(u,v); update2(id[son[u]],id[v],1,n,1);}int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif int T; scanf("%d",&T); while(T--){ init(); scanf("%d",&n); int u,v,w; for(int i=1;i

 

转载于:https://www.cnblogs.com/xiuwenli/p/9493477.html

你可能感兴趣的文章
SQL多表连接查询(详细实例)
查看>>
Http中涉及到的知识点总结
查看>>
测试计划
查看>>
adb命令记录
查看>>
Ecstore Nginx Rewrite(去掉链接中的index.php) ECSTORE 伪静态
查看>>
Dash
查看>>
BZOJ 1876: [SDOI2009]SuperGCD
查看>>
swift初学日志
查看>>
CCF真题之出现次数最多的数
查看>>
Eclipse上GIT插件_客户端配置
查看>>
使用HANA Web-based Development Workbench创建最简单的Server Side JavaScript
查看>>
JavaScript浏览器对象之二Document对象
查看>>
算法导论 第二部分——排序和顺序统计量
查看>>
监督学习——AdaBoost元算法提高分类性能
查看>>
SharePoint 使用代码创建 SPWeb/SPSiite/SPWebApplication以及WebPart添加到页面与删除 (三)...
查看>>
[原创]在Linux系统Ubuntu14.04上安装部署docker。
查看>>
网络对抗技术 实验四
查看>>
关联Anaconda和最新Pycharm2018.3.2
查看>>
DataGridView列的宽度、行的高度自动调整
查看>>
内部网关协议 (IGP)
查看>>