树链剖分专题
2015-06-17 22:06
363 查看
学习了一下树链剖分,找了几个有意义的题目训练一下
前4题是基础训练, A、B是AOV树(点记录信息) C、D是AOE树(边记录信息)
*注意一下poj好像是提交的代码包含/**/这样的注释会出问题
A、HDU 3966
题意:给你N个点M条边的一棵AOV树,有P次操作
操作分别是:‘I’:将C1到C2路径上的点增加K;
‘D’:将C1到C2路径上的点减少K;
‘Q’:问你C点上的权;
解:树链剖分基础题,需要注意的是杭电的服务器是windows的,代码中加入用下面这句话扩栈
View Code
前4题是基础训练, A、B是AOV树(点记录信息) C、D是AOE树(边记录信息)
*注意一下poj好像是提交的代码包含/**/这样的注释会出问题
A、HDU 3966
题意:给你N个点M条边的一棵AOV树,有P次操作
操作分别是:‘I’:将C1到C2路径上的点增加K;
‘D’:将C1到C2路径上的点减少K;
‘Q’:问你C点上的权;
解:树链剖分基础题,需要注意的是杭电的服务器是windows的,代码中加入用下面这句话扩栈
#pragma comment(linker, "/STACK:1024000000,1024000000")
/* * Problem: * Author: SHJWUDP * Created Time: 2015/6/11 星期四 15:57:34 * File Name: 233.cpp * State: * Memo: */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int INF=0x7f7f7f7f; const int MaxA=1e4+7; struct Edge { int v, nt; int w; Edge() {} Edge(int v, int nt, int w):v(v), nt(nt), w(w){} } edges[MaxA<<1]; int head[MaxA], edgeNum; struct SegmentTree { int n; struct Node { int mx, mi; int mark; } c[MaxA<<2]; int *val; int p, v; int L, R; #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define RUSH Node& u=c[rt]; Node& ls=c[rt<<1]; Node& rs=c[rt<<1|1]; void pushUp(int rt) { RUSH u.mx=max(ls.mx, rs.mx); u.mi=min(ls.mi, rs.mi); } void pushDown(int rt) { RUSH if(u.mark) { ls.mx=-ls.mx; ls.mi=-ls.mi; swap(ls.mx, ls.mi); ls.mark^=1; rs.mx=-rs.mx; rs.mi=-rs.mi; swap(rs.mx, rs.mi); rs.mark^=1; u.mark=0; } } void doBuild(int l, int r, int rt) { c[rt].mark=0; if(l==r) { c[rt].mx=c[rt].mi=val[l]; } else { int m=(l+r)>>1; doBuild(lson); doBuild(rson); pushUp(rt); } } void build(int n, int *val) { this->n=n; this->val=val; doBuild(1, n, 1); } void doChange(int l, int r, int rt) { if(l==r) { c[rt].mx=c[rt].mi=v; } else { pushDown(rt); int m=(l+r)>>1; if(p<=m) doChange(lson); else doChange(rson); pushUp(rt); } } void change(int p, int v) { this->p=p; this->v=v; doChange(1, n, 1); } void doNegate(int l, int r, int rt) { if(L<=l && r<=R) { c[rt].mx=-c[rt].mx; c[rt].mi=-c[rt].mi; swap(c[rt].mx, c[rt].mi); c[rt].mark^=1; } else { pushDown(rt); int m=(l+r)>>1; if(L<=m) doNegate(lson); if(m<R) doNegate(rson); pushUp(rt); } } void negate(int L, int R) { this->L=L; this->R=R; doNegate(1, n, 1); } int doQuery(int l, int r, int rt) { if(L<=l && r<=R) { return c[rt].mx; } else { pushDown(rt); int m=(l+r)>>1; int res=-INF; if(L<=m) res=max(res, doQuery(lson)); if(m<R) res=max(res, doQuery(rson)); return res; } } int query(int L, int R) { this->L=L; this->R=R; return doQuery(1, n, 1); } #undef lson #undef rson #undef RUSH } st; int N; int oval[MaxA], val[MaxA]; void init() { edgeNum=0; memset(head, -1, sizeof(head)); } void addEdge(int u, int v, int w) { edges[edgeNum]=Edge(v, head[u], w); head[u]=edgeNum++; } namespace LCT { int fa[MaxA]; int siz[MaxA]; int son[MaxA]; int dep[MaxA]; int top[MaxA]; int w[MaxA]; int id; int e2p[MaxA]; ///边到点的映射 int dfs1(int u, int d) { siz[u]=1; dep[u]=d; son[u]=-1; for(int i=head[u]; ~i; i=edges[i].nt) { Edge& e=edges[i]; if(e.v==fa[u]) continue; e2p[(i>>1)+1]=e.v; ///边到点的映射 fa[e.v]=u; oval[e.v]=e.w; ///以点代边 siz[u]+=dfs1(e.v, d+1); if(son[u]==-1 || siz[son[u]]<siz[e.v]) son[u]=e.v; } return siz[u]; } void dfs2(int u, int tp) { w[u]=++id; top[u]=tp; if(~son[u]) dfs2(son[u], tp); for(int i=head[u]; ~i; i=edges[i].nt) { Edge& e=edges[i]; if(e.v==fa[u] || e.v==son[u]) continue; dfs2(e.v, e.v); } } void init() { int root=1; id=0; oval[root]=-INF; ///以点代边,根结点不代表任何边 fa[root]=-1; dfs1(root, 0); dfs2(root, root); for(int i=1; i<=N; i++) { val[w[i]]=oval[i]; } st.build(N, val); } void change(int p, int v) { st.change(w[e2p[p]], v); } int find(int u, int v, int op) { int res=-INF; int f1=top[u], f2=top[v]; while(f1!=f2) { if(dep[f1]<dep[f2]) { swap(f1, f2); swap(u, v); } if(op==0) res=max(res, st.query(w[f1], w[u])); else st.negate(w[f1], w[u]); u=fa[f1]; f1=top[u]; } if(u==v) return res; if(dep[u]>dep[v]) swap(u, v); if(op==0) res=max(res, st.query(w[u]+1, w[v])); else st.negate(w[u]+1, w[v]); return res; } } int main() { #ifndef ONLINE_JUDGE freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif int T; scanf("%d", &T); while(T--) { scanf("%d", &N); init(); for(int i=1; i<N; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); addEdge(a, b, c); addEdge(b, a, c); } LCT::init(); char op[7]; while(scanf("%s", op), op[0]!='D') { int a, b; scanf("%d%d", &a, &b); switch(op[0]) { case 'C': LCT::change(a, b); break; case 'N': LCT::find(a, b, 1); break; default: printf("%d\n", LCT::find(a, b, 0)); } } } return 0; }
View Code
相关文章推荐
- 动态定义一个方法
- OpenGL学习之路--StartPoint
- iOS-UI控件之UIImageView
- 数据库设计说明书
- 《构建之法》13,14,15,16,17章读后感
- Opencv 笔记 opencv tutorial 2.1节 mat
- Struts2工具类
- shell 文本单词计数
- Leetcode---(104)Maximum Depth of Binary Tree
- 资源管理
- 《大道至简——软件工程实践者的思想》读书笔记之三
- 黑马程序员-----------网络编程
- 2015061706 - 工作反思
- 详细设计说明书
- JDK之HashMap、HashSet分析
- 概要设计说明书
- position为absolute的元素如何实现居中
- 聊一聊Horizon vGPU技术
- map集合框架
- 稳定模式在RESTful架构中的应用