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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SPOJ 375 query on a tree 树链剖分

發(fā)布時(shí)間:2024/4/17 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SPOJ 375 query on a tree 树链剖分 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題意:

給一棵樹型數(shù)據(jù)結(jié)構(gòu)

①支持修改邊的權(quán)值 ? ? ?②支持成段邊權(quán)最值查詢

樹鏈剖分入門題、

?

樹鏈剖分+線段樹

用的notonlysuccess的線段樹——不開結(jié)構(gòu)體事先預(yù)處理的那種

我以前寫的都是結(jié)構(gòu)體的那種~

?

View Code 1 #include <iostream> 2 #include <algorithm> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <cstring> 6 7 //notonlysuccess版線段樹-樹鏈剖分 8 9 #define N 20010 10 11 using namespace std; 12 13 int d[N][3]; 14 int to[N<<1],next[N<<1]; 15 int mx[N]; 16 int root,tot,cnt,n,m,cas; 17 int head[N],dep[N],wnum[N],fa[N],top[N],son[N],sz[N]; 18 //sz[x]樹的大小 dep[x]深度 top[x] x所在重路徑中深度最小的點(diǎn) fa[x]父親節(jié)點(diǎn) son[x]重兒子 wnum[x] x與其父親之間的邊的編號(hào) 19 20 inline void add(int u,int v) 21 { 22 to[cnt]=v; next[cnt]=head[u]; head[u]=cnt++; 23 } 24 25 inline void dfs(int x)//dfs求出fa[x],son[x],dep[x],sz[x] 26 { 27 sz[x]=1; son[x]=0; 28 for(int i=head[x];~i;i=next[i]) 29 if(fa[x]!=to[i]) 30 { 31 fa[to[i]]=x; 32 dep[to[i]]=dep[x]+1; 33 dfs(to[i]); 34 if(sz[to[i]]>sz[son[x]]) son[x]=to[i];//重邊 35 sz[x]+=sz[to[i]]; 36 } 37 } 38 39 inline void build(int x,int fx)//求出top[x],wnum[x](邊的編號(hào)) 40 { 41 wnum[x]=++tot; top[x]=fx; 42 if(son[x]!=0) build(son[x],top[x]);//保證重邊邊權(quán)相連 43 for(int i=head[x];~i;i=next[i]) 44 if(to[i]!=son[x]&&to[i]!=fa[x]) build(to[i],to[i]); 45 } 46 47 inline void updata(int x,int lt,int rt,int wn,int w) 48 { 49 if(wn>rt||wn<lt) return; 50 if(lt==rt) {mx[x]=w; return;} 51 int mid=(lt+rt)>>1; 52 int ls=x<<1,rs=ls+1; 53 updata(ls,lt,mid,wn,w); 54 updata(rs,mid+1,rt,wn,w); 55 mx[x]=max(mx[ls],mx[rs]); 56 } 57 58 inline int maxlen(int x,int lt,int rt,int l,int r)//求邊的編號(hào)在[l,r]之間的最大邊權(quán) 59 { 60 if(l>rt||r<lt) return 0; 61 if(l<=lt&&rt<=r) return mx[x]; 62 int mid=(lt+rt)>>1; 63 int ls=x<<1,rs=ls+1; 64 return max(maxlen(ls,lt,mid,l,r),maxlen(rs,mid+1,rt,l,r)); 65 } 66 67 inline int query(int x,int y) 68 { 69 int fx=top[x],fy=top[y],ans=0; 70 while(fx!=fy) 71 { 72 if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy); 73 ans=max(ans,maxlen(1,1,tot,wnum[fx],wnum[x])); 74 x=fa[fx]; fx=top[x]; 75 } 76 if(x==y) return ans; 77 if(dep[x]>dep[y]) swap(x,y); 78 return max(ans,maxlen(1,1,tot,wnum[son[x]],wnum[y])); 79 } 80 81 inline void read() 82 { 83 scanf("%d",&n); 84 root=(n+1)>>1; 85 fa[root]=dep[root]=cnt=tot=0; 86 memset(sz,0,sizeof sz); 87 memset(head,-1,sizeof head); 88 memset(mx,0,sizeof mx); 89 for(int i=1;i<n;i++) 90 { 91 scanf("%d%d%d",&d[i][0],&d[i][1],&d[i][2]); 92 add(d[i][0],d[i][1]); 93 add(d[i][1],d[i][0]); 94 } 95 dfs(root); 96 build(root,root); 97 for(int i=1;i<n;i++) 98 { 99 if(dep[d[i][0]]>dep[d[i][1]]) swap(d[i][0],d[i][1]); 100 updata(1,1,tot,wnum[d[i][1]],d[i][2]); 101 } 102 } 103 104 inline void go() 105 { 106 char str[10]; int a,b; 107 while(true) 108 { 109 scanf("%s",str); 110 if(str[0]=='D') return; 111 scanf("%d%d",&a,&b); 112 if(str[0]=='Q') printf("%d\n",query(a,b)); 113 else updata(1,1,tot,wnum[d[a][1]],b); 114 } 115 } 116 117 int main() 118 { 119 scanf("%d",&cas); 120 while(cas--) read(),go(); 121 return 0; 122 }

?

又寫了一發(fā),和之前風(fēng)格完全不同。。

?

View Code 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <algorithm> 6 7 #define N 100000 8 #define M 200000 9 #define INF 1e9 10 11 using namespace std; 12 13 int head[N],next[M],to[M],len[M]; 14 int son[N],fa[N],dat[M],bh[M],pre[N],dep[N],sz[N],top[N]; 15 int q[N],mx[M<<2]; 16 int n,cnt,tot; 17 18 inline void add(int u,int v,int w) 19 { 20 to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++; 21 } 22 23 inline void init() 24 { 25 memset(son,-1,sizeof son); 26 memset(fa,0,sizeof fa); 27 memset(head,-1,sizeof head); cnt=0; 28 tot=0; 29 } 30 31 inline void prep() 32 { 33 int h=1,t=2,sta; 34 q[1]=1; dep[1]=1; 35 while(h<t) 36 { 37 sta=q[h++]; sz[sta]=1; 38 for(int i=head[sta];~i;i=next[i]) 39 if(fa[sta]!=to[i]) 40 { 41 fa[to[i]]=sta; 42 dep[to[i]]=dep[sta]+1; 43 pre[to[i]]=len[i]; 44 q[t++]=to[i]; 45 } 46 } 47 for(int j=t-1;j>=1;j--) 48 { 49 sta=q[j]; 50 for(int i=head[sta];~i;i=next[i]) 51 if(fa[sta]!=to[i]) 52 { 53 sz[sta]+=sz[to[i]]; 54 if(son[sta]==-1||sz[to[i]]>sz[to[son[sta]]]) son[sta]=i; 55 } 56 } 57 for(int i=1;i<t;i++) 58 { 59 sta=q[i]; 60 if(to[son[fa[sta]]]==sta) top[sta]=top[fa[sta]]; 61 else top[sta]=sta; 62 } 63 } 64 65 inline void rewrite() 66 { 67 for(int i=1;i<=n;i++) 68 if(top[i]==i) 69 for(int j=son[i];~j;j=son[to[j]]) 70 { 71 bh[(j>>1)+1]=++tot; 72 dat[tot]=len[i]; 73 } 74 } 75 76 inline void pushup(int u) 77 { 78 mx[u]=max(mx[u<<1],mx[u<<1|1]); 79 } 80 81 inline void build(int u,int L,int R) 82 { 83 if(L==R) {mx[u]=dat[L];return;} 84 int MID=(L+R)>>1; 85 build(u<<1,L,MID); build(u<<1|1,MID+1,R); 86 pushup(u); 87 } 88 89 inline void read() 90 { 91 init(); 92 scanf("%d",&n); 93 for(int i=1,a,b,c;i<n;i++) 94 { 95 scanf("%d%d%d",&a,&b,&c); 96 add(a,b,c); add(b,a,c); 97 } 98 99 prep(); 100 rewrite(); 101 build(1,1,tot); 102 } 103 104 inline void updata(int u,int L,int R,int pos,int sp) 105 { 106 if(L==R) {mx[u]=sp;return;} 107 int MID=(L+R)>>1; 108 if(pos<=MID) updata(u<<1,L,MID,pos,sp); 109 else updata(u<<1|1,MID+1,R,pos,sp); 110 pushup(u); 111 } 112 113 inline int querymax(int u,int L,int R,int l,int r) 114 { 115 if(l<=L&&R<=r) return mx[u]; 116 int MID=(L+R)>>1,res=-INF; 117 if(l<MID) res=max(res,querymax(u<<1,L,MID,l,r)); 118 if(MID<r) res=max(res,querymax(u<<1|1,MID+1,R,l,r)); 119 return res; 120 } 121 122 inline int getmax(int x,int y) 123 { 124 int res=-INF; 125 while(top[x]!=top[y]) 126 { 127 if(dep[top[x]]<dep[top[y]]) swap(x,y); 128 res=max(res,querymax(1,1,tot,bh[top[x]],bh[x])); 129 res=max(res,pre[top[x]]); 130 x=fa[top[x]]; 131 } 132 if(bh[x]>bh[y]) swap(x,y); 133 res=max(res,querymax(1,1,tot,bh[x],bh[y])); 134 return res; 135 } 136 137 inline void go() 138 { 139 char str[10];int a,b; 140 while(scanf("%s",str)) 141 { 142 if(str[0]=='D') break; 143 scanf("%d%d",&a,&b); 144 if(str[0]=='C') updata(1,1,tot,bh[a],b); 145 else printf("%d\n",getmax(a,b)); 146 } 147 } 148 149 int main() 150 { 151 int cas;scanf("%d",&cas); 152 while(cas--) read(),go(); 153 return 0; 154 }

?

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/proverbs/archive/2013/01/02/2842572.html

總結(jié)

以上是生活随笔為你收集整理的SPOJ 375 query on a tree 树链剖分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。