题目:
树链剖分:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace  std;
#define MAXN 10024
#define MAXLOG 14
#define INF 0x7fffffff
int n,T,size[MAXN+10],dep[MAXN+10],fa[MAXN+10][MAXLOG+1],wt[MAXN+10]={0,-INF},bl[MAXN+10],length[MAXN+10],id2v[MAXN+10];
int tmax[MAXN*4+10],*ttop,*root[MAXN+10],pos[MAXN+10];
bool f;
struct node{int v,wt,pos;node *next;
}*adj[MAXN+10],edge[MAXN*2+10],*ecnt;
void addedge(int u,int v,int wt,int pos){node *p=++ecnt;p->v=v;p->wt=wt;p->pos=pos;p->next=adj[u];adj[u]=p;
}
void Read(int &x){char c;while(c=getchar(),c!=EOF)if(c>='0'&&c<='9'){x=c-'0';while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';ungetc(c,stdin);return;}
}
void dfs1(int u,int father){fa[u][0]=father;dep[u]=dep[father]+1;size[u]=1;for(int i=1;i<=MAXLOG;i++)fa[u][i]=fa[fa[u][i-1]][i-1];for(node *p=adj[u];p;p=p->next){if(p->v!=father){id2v[p->pos]=p->v;wt[p->v]=p->wt;dfs1(p->v,u);size[u]+=size[p->v];}}
}
inline int *NewTree(int len){int *ret=ttop;ttop+=len*4;return ret;
}
void insert(int *tmax,int i,int l,int r,int pos,int wt){if(l==r){tmax[i]=wt;return;}int mid=(l+r)>>1;if(pos<=mid)insert(tmax,i<<1,l,mid,pos,wt);elseinsert(tmax,(i<<1)+1,mid+1,r,pos,wt);tmax[i]=max(tmax[i<<1],tmax[(i<<1)+1]);
}
void dfs2(int u,int len,int father){int heavy=0,i;for(node *p=adj[u];p;p=p->next)if(p->v!=father&&size[p->v]>size[heavy])heavy=p->v;if(!heavy){int tp=u;for(i=1;i<len;i++)tp=fa[tp][0];root[tp]=NewTree(len);length[tp]=len;for(i=len;i;i--){bl[u]=tp;pos[u]=i;insert(root[tp],1,1,len,i,wt[u]);u=fa[u][0];}return;}dfs2(heavy,len+1,u);for(node *p=adj[u];p;p=p->next){if(p->v!=father&&p->v!=heavy)dfs2(p->v,1,u);}
}
void init(){Read(n);int i,u,v,wt;for(i=1;i<n;i++){Read(u),Read(v),Read(wt);addedge(u,v,wt,i);addedge(v,u,wt,i);}dfs1(1,0);dfs2(1,1,0);
}
int LCA(int a,int b){if(dep[a]<dep[b])swap(a,b);int i;for(i=MAXLOG;i>=0;i--)if(dep[a]-(1<<i)>=dep[b])a=fa[a][i];if(a==b)return a;for(i=MAXLOG;i>=0;i--)if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];return fa[a][0];
}
int find(int *tmax,int i,int l,int r,int ll,int rr){if(l>=ll&&r<=rr)return tmax[i];if(l>rr||r<ll)return -INF;int mid=(l+r)>>1;return max(find(tmax,i<<1,l,mid,ll,rr),find(tmax,(i<<1)+1,mid+1,r,ll,rr));
}
int query(int lca,int a){int ret=-INF;while(lca!=a){if(bl[a]!=bl[lca]){ret=max(find(root[bl[a]],1,1,length[bl[a]],1,pos[a]),ret);a=fa[bl[a]][0];}else{ret=max(find(root[bl[a]],1,1,length[bl[a]],pos[lca]+1,pos[a]),ret);break;}}return ret;
}
void solve(){char s[10];int lca,a,b;while(scanf("%s",s),s[0]!='D'){Read(a),Read(b);if(s[0]=='Q'){lca=LCA(a,b);printf("%d\n",max(query(lca,a),query(lca,b)));}else{wt[id2v[a]]=b;insert(root[bl[id2v[a]]],1,1,length[bl[id2v[a]]],pos[id2v[a]],b);}}
}
int main()
{Read(T);while(T--){memset(fa,0,sizeof fa);memset(adj,0,sizeof adj);memset(tmax,0,sizeof tmax);ttop=tmax;ecnt=edge;init();solve();}
}

动态树(LCT):

#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAXN 10000
using namespace std;
int n,e2id[MAXN+10],T;
void Read(int &x){char c;while(c=getchar(),c!=EOF)if(c>='0'&&c<='9'){x=c-'0';while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';ungetc(c,stdin);return;}
}
struct node{int val,mx,wt;node *ch[2],*fa;bool pre;
}splay_tree[MAXN+10];
struct nodedge{int v,wt,pos;nodedge *next;
}edge[MAXN*2+10],*ecnt=edge,*adj[MAXN+10];
inline void addedge(int u,int v,int wt,int pos){nodedge *p=++ecnt;p->v=v;p->wt=wt;p->next=adj[u];p->pos=pos;adj[u]=p;
}
inline void  init(node *p){p->ch[0]=p->ch[1]=0;p->pre=0;
}
void dfs(int u,int dep,int fa){node *x=&splay_tree[u],*y;init(x);x->val=dep;for(nodedge *p=adj[u];p;p=p->next){if(p->v!=fa){e2id[p->pos]=p->v;y=&splay_tree[p->v];y->mx=y->wt=p->wt;y->fa=x;dfs(p->v,dep+1,u);}}
}
void read(){Read(n);int u,v,wt,i;for(i=1;i<n;i++){Read(u),Read(v),Read(wt);addedge(u,v,wt,i);addedge(v,u,wt,i);}init(&splay_tree[1]);splay_tree[1].fa=0;dfs(1,1,0);
}
inline int Get_max(node *p){return p?p->mx:0;
}
inline void update(node *p){p->mx=max(p->wt,max(Get_max(p->ch[0]),Get_max(p->ch[1])));
}
void Rotate(node *x,int d){node *y=x->fa;if(y->fa&&y->pre)y->fa->ch[y==y->fa->ch[1]]=x;x->fa=y->fa;if(x->ch[d])x->ch[d]->fa=y;y->ch[!d]=x->ch[d];x->ch[d]=y;y->fa=x;swap(x->pre,y->pre);update(y);
}
void splay(node *x){node *y,*z;while(x->pre){y=x->fa;z=y->fa;if(!z||!y->pre){if(x==y->ch[0])Rotate(x,1);elseRotate(x,0);}else{if(y==z->ch[0])if(x==y->ch[0]){Rotate(y,1);Rotate(x,1);}else{Rotate(x,0);Rotate(x,1);}elseif(x==y->ch[1]){Rotate(y,0);Rotate(x,0);}else{Rotate(x,1);Rotate(x,0);}}}update(x);
}
void access(int a){node *x=&splay_tree[a],*y;splay(x);if(x->ch[1]){x->ch[1]->pre=0;x->ch[1]=0;}update(x);while(1){y=x->fa;if(!y)return;splay(y);if(y->ch[1])y->ch[1]->pre=0;y->ch[1]=x;x->pre=1;splay(x);}splay(x);
}
int query(int a){node *x=&splay_tree[a],*y;int ans;splay(x);if(!x->fa)return Get_max(x->ch[1]);if(x->ch[1]){x->ch[1]->pre=0;x->ch[1]=0;}update(x);while(1){y=x->fa;splay(y);ans=Get_max(y->ch[1]);if(y->ch[1])y->ch[1]->pre=0;y->ch[1]=x;x->pre=1;if(!y->fa){ans=max(ans,Get_max(x));splay(x);return ans;}splay(x);}
}
void solve(){char s[10];int a,b;while(scanf("%s",s),s[0]!='D')if(s[0]=='Q'){Read(a),Read(b);access(a);printf("%d\n",query(b));}else{Read(a),Read(b);access(e2id[a]);splay_tree[e2id[a]].wt=b;update(&splay_tree[e2id[a]]);}
}
int main()
{Read(T);while(T--){memset(adj,0,sizeof adj);ecnt=edge;read();solve();}
}

转载于:https://www.cnblogs.com/outerform/p/5921909.html

【高级数据结构】[SPOJ QTREE]树链剖分/动态树各一模板相关推荐

  1. URAL1553 Caves and Tunnels 树链剖分 动态树

    URAL1553 维护一棵树,随时修改某个节点的权值,询问(x,y)路径上权值最大的点. 树是静态的,不过套动态树也能过,时限卡的严就得上树链剖分了. 还是那句话 splay的核心是splay(x) ...

  2. BZOJ4127Abs——树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  3. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MB Submit: 1153  Solved: 421 [Submit][Sta ...

  4. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  5. CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一张 n 个点 m 条边组成的带权无向图,现在对于每条边来说,确定一下其分类: 一定是最小生成树上的边 可能是最小生成树上的边 一定不是最小生成树的边 题目分析:两种 ...

  6. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)

    题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...

  7. POJ 3237 树链剖分学习(树链剖分小结)

    一个地方wa了3发,找了一组数组发现的错误,太蠢,就是两个人数作交换写成了 a=b ,b=a.最近智商真是感人.这道题是由spoj375这题改编的,多了一个取反的操作,这个操作只需要多维护一个最小值就 ...

  8. P2486 [SDOI2011]染色(树链剖分+线段树)

    题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q ...

  9. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

最新文章

  1. PHP 高级编程之多线程
  2. Java、Python、Go 哪个后端编程语言适合web前端工程师学习?
  3. 【Android】ADT中使用NDK编译已有的C++实现的库文件
  4. 不讲武德的微信,又来一波新功能!
  5. python--pandas 分位数
  6. css中的媒体查询_CSS中的媒体查询
  7. 【LeetCode】3月25日打卡-Day10
  8. 用Python一次性把论文作图与数据处理全部搞定!
  9. os系统好用的学术笔记软件_可靠软件系统的设计方法:学术文章摘要
  10. 同一个项目,项目名称不一致,这两个项目同时在Eclipse中出现
  11. linq 根据指定条件返回集合中不重复的元素
  12. RQNOJ 34 紧急援救 解题报告
  13. linux 服务器共享文件客户端查看,在Linux下查看共享文件夹
  14. K210 Draco AI环境的搭建(1)
  15. 水下声学的基本声学量介绍
  16. java的动物打一生肖,吉祥的动物是什么生肖 指哪个生肖 打一生肖
  17. 3060ti配什么cpu和主板
  18. 关于联合体及联合体嵌套结构体
  19. 手机改小视窗什么意思_小窗口,大作用!
  20. QQ聊天记录丢了怎么恢复

热门文章

  1. git多人协作冲突解决方法
  2. TeskLink—增加一种需求类型(业务流程)(version1.9.8)
  3. IT人的理性、激情与爱情
  4. 边缘检测与轮廓检测有什么区别?
  5. 理解 Go defer
  6. 计算机到计算机 临时网络,电脑如何设置临时网络
  7. EVC4.0+AdoCe3.1访问Access数据库全攻略(附带说明及例程)
  8. 在对话框中加入属性页
  9. FCKeditor 在ASP.Net 中的使用说明
  10. 转 AIX7.2+11.2.0.4RAC实施