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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

POJ3237 树的维护

發(fā)布時間:2023/12/31 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ3237 树的维护 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

P1424 - [POJ3237]樹的維護(hù)

Description

給你由N個結(jié)點(diǎn)組成的樹。樹的節(jié)點(diǎn)被編號為1到N,邊被編號為1到N-1。每一條邊有一個權(quán)值。然后你要在樹上執(zhí)行一系列指令。指令可以是如下三種之一:
CHANGE i v:將第i條邊的權(quán)值改成v。
NEGATE a b:將點(diǎn)a到點(diǎn)b路徑上所有邊的權(quán)值變成其相反數(shù)。
QUERY a b:找出點(diǎn)a到點(diǎn)b路徑上各邊的最大權(quán)值。

Input

第一行有一個整數(shù)N(N<=10000)。
接下來N-1行每行有三個整數(shù)a,b,c,代表點(diǎn)a和點(diǎn)b之間有一條權(quán)值為c的邊。這些邊按照其編號從小到大給出。
接下來是若干條指令(不超過10^5條),都按照上面所說的格式。
最后一行是"DONE".

Output

對每個“QUERY”指令,輸出一行,即路徑上各邊的最大權(quán)值。

Sample Input

3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE

Sample Output

1
3

Hint

Source

POJ 3237 Tree
樹鏈剖分, 動態(tài)樹, LCA

?

線段樹,TMD調(diào)了我一個晚上+半個上午,最后才知道是因為lazy標(biāo)記沒有下放,woc

1 #define ls o*2 2 #define rs o*2+1 3 4 #define inf 1999999999 5 #include<algorithm> 6 #include<iostream> 7 #include<iomanip> 8 #include<cstring> 9 #include<cstdlib> 10 #include<cstdio> 11 #include<queue> 12 #include<ctime> 13 #include<cmath> 14 #include<stack> 15 #include<map> 16 #include<set> 17 using namespace std; 18 const int N=10010,M=N-1; 19 struct E{ 20 int to,net,w; 21 int fr; 22 }e[M*2]; 23 struct TREE{ 24 int bj,Max,Min; 25 TREE(){ 26 bj=1; 27 } 28 }tr[N*4]; 29 int head[N],n,num_e; 30 void add(int x,int y,int w) { 31 e[++num_e].to=y;e[num_e].net=head[x];head[x]=num_e;e[num_e].w=w;e[num_e].fr=x; 32 } 33 void down(int); 34 int dep[N],top[N],son[N],tid[N],pos[N],fa[N],siz[N],val[N],idx; 35 int W[N],len[N*4]; 36 int B[M*2]; 37 void dfs1(int x,int fu) { 38 siz[x]=1; 39 dep[x]=dep[fu]+1;// 40 son[x]=0; 41 fa[x]=fu;// meinong 42 for(int i=head[x];i;i=e[i].net) { 43 int to=e[i].to; 44 if(to!=fu) { 45 val[to]=e[i].w; 46 dfs1(to,x); 47 siz[x] += siz[to];// 這一步竟然忘了!!!! 48 if(siz[to]>siz[son[x]]) son[x]=to; 49 // printf("x=%d son=%d",x,son[x]);P 50 } 51 } 52 } 53 void dfs2(int x,int tp) { 54 tid[x]=++idx; 55 pos[idx]=x; 56 top[x]=tp; 57 W[idx]=val[x];// 58 if(son[x]==0) return; 59 dfs2(son[x],tp); 60 for(int i=head[x];i;i=e[i].net) 61 if(e[i].to!=son[x]&&dep[e[i].to]>dep[x]) { 62 dfs2(e[i].to,e[i].to); 63 } 64 } 65 void build(int o,int L,int R) { 66 if(L==R) { 67 if(L==1) tr[o].Max=-inf,tr[o].Min=inf; 68 else 69 tr[o].Max=W[L],tr[o].Min=W[L]; 70 return; 71 } 72 int mid=(L+R)>>1; 73 build(ls,L,mid); 74 build(rs,mid+1,R); 75 tr[o].Max=max(tr[ls].Max,tr[rs].Max); 76 tr[o].Min=min(tr[ls].Min,tr[rs].Min); 77 } 78 void Update(int o,int L,int R,int p,int x) { 79 if(L!=R) down(o); 80 if(p==L&&R==p) { 81 tr[o].Max=x;tr[o].Min=x; 82 return; 83 } 84 int mid=(L+R)>>1; 85 if(p<=mid) Update(ls,L,mid,p,x); 86 else Update(rs,mid+1,R,p,x); 87 tr[o].Max=max(tr[ls].Max,tr[rs].Max); 88 tr[o].Min=min(tr[ls].Min,tr[rs].Min); 89 } 90 void GG(int,int,int,int,int); 91 // GG Update() 92 void solveG(int x,int y) { 93 while(top[x]!=top[y]) { 94 if(dep[top[x]]>dep[top[y]]) swap(x,y); 95 GG(1,1,n,tid[top[y]],tid[y]); 96 y=fa[top[y]]; 97 } 98 if(dep[x]>dep[y]) swap(x,y); 99 if(x==y) return;// y 100 GG(1,1,n,tid[x]+1,tid[y]); 101 } 102 void down(int o) { 103 int mi; 104 int k=tr[o].bj; 105 if(tr[o].bj==1) return; 106 mi=tr[ls].Min;tr[ls].Min=k*tr[ls].Max,tr[ls].Max=mi*k;//mi 107 mi=tr[rs].Min;tr[rs].Min=k*tr[rs].Max,tr[rs].Max=k*mi; 108 tr[o].bj=1;//復(fù)原 // tr[o].bj==1 109 tr[ls].bj*=-1; 110 tr[rs].bj*=-1;// 111 return; 112 } 113 int querymax(int o,int L,int R,int l,int r) { 114 if(L!=R) down(o); 115 if(l<=L&&R<=r) { 116 return tr[o].Max; 117 } 118 int Max=-inf; 119 int mid=(L+R)>>1; 120 if(l<=mid) Max=max(Max,querymax(ls,L,mid,l,r)); 121 if(r>mid) Max=max(Max,querymax(rs,mid+1,R,l,r)); 122 return Max; 123 } 124 125 void GG(int o,int L,int R,int l,int r) { 126 if(L!=R) down(o); 127 if(l<=L&&R<=r) { 128 int mi=tr[o].Min,ma=tr[o].Max; 129 // tr[o].bj*=-1; 130 tr[o].bj=-1; 131 tr[o].Min=-ma;tr[o].Max=-mi; 132 return; 133 } 134 int mid=(L+R)>>1; 135 if(l<=mid) GG(ls,L,mid,l,r); 136 if(r>mid) GG(rs,mid+1,R,l,r); 137 tr[o].Max=max(tr[ls].Max,tr[rs].Max); 138 tr[o].Min=min(tr[ls].Min,tr[rs].Min); 139 } 140 int solvemax(int x,int y) { 141 int Max=-inf; 142 143 while(top[x]!=top[y]) { 144 if(dep[top[x]]>dep[top[y]]) swap(x,y); 145 Max=max(Max,querymax(1,1,n,tid[top[y]],tid[y])); 146 y=fa[top[y]]; 147 } 148 if(dep[x]>dep[y]) swap(x,y); 149 if(x==y) return Max; 150 Max=max(Max,querymax(1,1,n,tid[x]+1,tid[y])); 151 return Max; 152 } 153 int main() { 154 155 cin>>n;int i; 156 for(i=1;i<n;i++) { 157 int x,y,w;scanf("%d%d%d",&x,&y,&w); 158 add(x,y,w); 159 B[i]=num_e; 160 add(y,x,w); 161 } 162 dfs1(1,0); 163 dfs2(1,1); 164 for(i=1;i<n;i++) { 165 int x=e[B[i]].fr,y=e[B[i]].to; 166 if(dep[x]<dep[y]) B[i]=y; 167 else B[i]=x; 168 } 169 build(1,1,n); 170 string s; 171 while(1) { 172 cin>>s; 173 int a,b;scanf("%d%d",&a,&b); 174 if(s[0]=='D') break; 175 else if(s[0]=='C') { 176 a=B[a]; 177 Update(1,1,n,tid[a],b); 178 } 179 else if(s[0]=='N') { 180 solveG(a,b); 181 } 182 else printf("%d\n",solvemax(a,b)); 183 } 184 return 0; 185 } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/ypz999/p/6621860.html

總結(jié)

以上是生活随笔為你收集整理的POJ3237 树的维护的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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