【高级数据结构】[SPOJ QTREE]树链剖分/动态树各一模板
2015-12-01 13:16
381 查看
题目:
树链剖分:
动态树(LCT):
树链剖分:
[code]#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); else insert(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):
[code]#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); else Rotate(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); } else if(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(); } }
相关文章推荐
- 7.数据结构之哈希表
- 数据结构实践——大数据集上排序算法性能的体验
- [数据结构]折半搜索、归并排序( 分治思想)
- EKAlgorithms-常用数据结构Objective-C语言实现一数组排序
- 《大话数据结构》之二叉树的四种遍历
- 浅谈算法和数据结构: 九 平衡查找树之红黑树
- [数据结构]队列的基本操作
- 【数据结构】建立和平衡AVL二叉树
- JavaScript数据结构 --- 散列
- 数据结构之栈
- 分治算法
- 数据结构例程——基数排序
- 数据结构例程——简单的计数排序
- 数据结构例程——归并排序
- 数据结构例程——选择排序之堆排序
- 枚举法的简单心得
- 【数据结构】栈结构操作示例
- 【数据结构】链表操作示例
- 【Educational Codeforces Round 2E】【STL-map 启发式合并 or 线段树动态开节点 】Lomsat gelral 一棵树每点一个颜色问每个节点子树的颜色众数之和
- 数据结构与算法-----队列-使用链表(链式结构)实现