日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

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

發布時間:2025/7/25 c/c++ 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【高级数据结构】[SPOJ QTREE]树链剖分/动态树各一模板 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目:
樹鏈剖分:

#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]树链剖分/动态树各一模板的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。