【COGS1672】【SPOJ375】QTREE,cogs1672spoj375
這是我的第一個邊權鏈剖
COGS上和SPOJ有點不一樣就是沒有多組資料了本質還是一樣的
我寫的是COGS那個其實改一改就可以去SPOJ AC了= -=
(可是我現在上不去SPOJ臥槽(╯‵□′)╯︵┻━┻)
【題目描述】
一天機房的夜晚,無數人在MC裡奮鬥著。。。
大家都知道礦產對於MC來說是多麼的重要,但由於礦越挖越少,勇士們不得不跑到更遠的地方挖礦,但這樣路途上就會花費相當大的時間,導致挖礦效率低下。
cjj提議修一條鐵路,大家一致同意。
大家都被CH分配了一些任務:
zjmfrank2012負責繪製出一個礦道地圖,這個地圖包括家(當然這也是一個礦,畢竟不把家掏空我們是不會走的),和無數個礦,所以大家應該可以想出這是一個無向無環圖,也就是一棵樹。
Digital_T和cstdio負責鋪鐵路。。所以這裡沒他們什麼事,兩位可以勞作去了。
這個時候song526210932和RMB突然發現有的礦道會刷怪,並且怪的數量會發生變化。作為採礦主力,他們想知道從一個礦到另一個礦的路上哪一段會最困難。。。(困難值用zjm的死亡次數表示)。
【輸入格式】
輸入檔案的第一行有一個整數N,代表礦的數量。礦的編號是1到N。
接下來N-1行每行有三個整數a,b,c,代表第i號礦和第j號礦之間有一條路,在初始時這條路的困難值為c。
接下來有若干行,每行是“CHANGE i ti”或者“QUERY a b”,前者代表把第i條路(路按所給順序從1到M編號)的困難值修改為ti,後者代表查詢a到b所經過的道路中的最大困難值。
輸入資料以一行“DONE”結束。
【輸出格式】
對每個“QUERY”操作,輸出一行一個正整數,即最大困難值。
【範例輸入】
3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE
【範例輸出】
1
3
【提示】
對於60%的資料,1≤N≤50
對於100%的資料,1≤N≤10000,1≤c≤1000000,1≤操作次數≤100000
【來源】
由GDFRWMY 改編自SPOJ 375 QTREE
資料by cstdio
邊權鏈剖略蛋疼
我用每條邊兩個端點裡深度比較大的那個以點權繼承這條邊的邊權
最後在Query_max函數在樹的統計Count基礎上稍微改了改就行了
(直接暴力用LCA會出傻逼的錯誤我一開始竟然沒注意到多虧zky學長提醒QUQ)
//AC code by CreationAugust#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXINT 0x7fffffff#define MAXN 100010#define lchild rt<<1,l,mid#define rchild rt<<1|1,mid+1,r#define ln rt<<1#define rn rt<<1|1using namespace std;int w;int val[MAXN];int size[MAXN],deep[MAXN],chain[MAXN],num[MAXN],fa[MAXN][18];bool vis[MAXN];int top,tp;int a,b;int u,v;int n,T;int x[MAXN],y[MAXN],z[MAXN];char ch[6];struct edge{ edge *next; int val; int to;}*prev[MAXN],e[MAXN*2];struct seg{ int maxn; int l; int r;}tree[MAXN*4];inline void insert(int u,int v,int w){ e[++top].to=v; e[top].val=w; e[top].next=prev[u]; prev[u]=&e[top];}inline void dfs1(int x){ size[x]=1; vis[x]=1; for (int i=1;i<=17;i++) { if (deep[x]<(1<<i)) break; fa[x][i]=fa[fa[x][i-1]][i-1]; } for (edge *i=prev[x];i;i=i->next) { int t=i->to; if (vis[t]) continue; deep[t]=deep[x]+1; fa[t][0]=x; dfs1(t); size[x]+=size[t]; }}inline void dfs2(int x,int last){ chain[x]=last; num[x]=++tp; int t=0; for (edge *i=prev[x];i;i=i->next) if (deep[i->to]>deep[x]&&size[t]<size[i->to]) t=i->to; if (!t) return; dfs2(t,last); for (edge *i=prev[x];i;i=i->next) if (deep[i->to]>deep[x]&&i->to!=t) dfs2(i->to,i->to);}inline void push_up(int rt){ tree[rt].maxn=max(tree[ln].maxn,tree[rn].maxn);}inline void build(int rt=1,int l=1,int r=n){ tree[rt].l=l; tree[rt].r=r; if (l==r) return; int mid=(l+r)>>1; build(lchild); build(rchild);}inline int lca(int a,int b){ if (deep[a]<deep[b]) swap(a,b); int t=deep[a]-deep[b]; for (int i=0;i<=17;i++) if (t&(1<<i)) a=fa[a][i]; for (int i=17;i>=0;i--) if (fa[a][i]!=fa[b][i]) { a=fa[a][i]; b=fa[b][i]; } if (a==b) return a; else return fa[a][0];}void modify(int rt,int l,int r,int w){ int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1; if (L==l&&r==R) { tree[rt].maxn=w; return; } if (l>mid) modify(rn,l,r,w); else if (r<=mid) modify(ln,l,r,w); else { modify(lchild,w); modify(rchild,w); } push_up(rt);} void Modify(int a,int b,int w){ while (chain[a]!=chain[b]) { modify(1,num[chain[a]],num[a],w); a=fa[chain[a]][0]; } modify(1,num[b],num[a],w);}inline int query_max(int rt,int l,int r){ int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1; if (L==l&&R==r) { return tree[rt].maxn; } if (l>mid) return query_max(rn,l,r); else if (r<=mid) return query_max(ln,l,r); else return max(query_max(lchild),query_max(rchild));}inline int Query_max(int a,int b){ int ret=-MAXINT; while (chain[a]!=chain[b]) { ret=max(ret,query_max(1,num[chain[a]],num[a])); a=fa[chain[a]][0]; } if (num[b]+1<=num[a]) ret=max(ret,query_max(1,num[b]+1,num[a])); return ret;}int main(){ freopen("qtree.in","r",stdin); freopen("qtree.out","w",stdout); scanf("%d",&n); for (int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&w); insert(u,v,w); insert(v,u,w); x[i]=u; y[i]=v; z[i]=w; } dfs1(1); dfs2(1,1); build(); for (int i=1;i<n;i++) { if (deep[x[i]]<deep[y[i]]) val[y[i]]=z[i]; else val[x[i]]=z[i]; } for (int i=1;i<=n;i++) modify(1,num[i],num[i],val[i]); while (1) { scanf("%s",ch); if (ch[1]=='H') { scanf("%d%d",&a,&b); if (deep[x[a]]<deep[y[a]]) modify(1,num[y[a]],num[y[a]],b); else modify(1,num[x[a]],num[x[a]],b); } else if (ch[1]=='U') { scanf("%d%d",&a,&b); int t=lca(a,b); printf("%d\n",max(Query_max(a,t),Query_max(b,t))); } else if (ch[1]=='O') break; }}