首页 > 代码库 > SPOJ - QTREE 375 Query on a tree 树链剖分+线段树
SPOJ - QTREE 375 Query on a tree 树链剖分+线段树
操作1:修改第k条边权。
操作2:询问两点间最大边权。
树链剖分,然后线段树维护最大值
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<set> #include<map> #include<queue> #include<vector> #include<string> #define eps 1e-12 #define INF 0x7fffffff #define maxn 11111 using namespace std; char str[maxn]; struct node { int to,next; } e[maxn<<1]; int head[maxn],en,n; int fa[maxn],siz[maxn],top[maxn],son[maxn],w[maxn],dep[maxn],id; int maxs[maxn<<2]; int d[maxn][3]; void init() { fa[1]=0; dep[1]=0; id=en=0; memset(head,-1,sizeof(head)); memset(siz,0,sizeof(siz)); memset(maxs,0,sizeof(maxs)); } void add(int a,int b) { e[en].to=b; e[en].next=head[a]; head[a]=en++; } void dfs(int now) { siz[now]=1; son[now]=0; for(int i=head[now]; ~i; i=e[i].next) { int to=e[i].to; if(to!=fa[now]) { fa[to]=now; dep[to]=dep[now]+1; dfs(to); if(siz[to]>siz[son[now]]) son[now]=to; siz[now]+=siz[to]; } } } void getid(int now,int root) { w[now]=++id; top[now]=root; if(son[now]) getid(son[now],top[now]); for(int i=head[now]; ~i; i=e[i].next) { if(e[i].to!=son[now]&&e[i].to!=fa[now]) { getid(e[i].to,e[i].to); } } } void update(int rt,int l,int r,int k,int add) { if(l==r) { maxs[rt]=add; return ; } int mid=(l+r)/2; int lson=(rt<<1); int rson=(rt<<1|1); if(k<=mid) update(lson,l,mid,k,add); else update(rson,mid+1,r,k,add); maxs[rt]=max(maxs[lson],maxs[rson]); } int query(int rt,int l,int r,int ql,int qr) { if(ql<=l&&r<=qr) return maxs[rt]; int mid=(l+r)/2; int lson=(rt<<1); int rson=(rt<<1|1); int tmp=0; if(ql<=mid) tmp=max(tmp,query(lson,l,mid,ql,qr)); if(qr>mid) tmp=max(tmp,query(rson,mid+1,r,ql,qr)); return tmp; } int find(int a,int b) { int f1=top[a]; int f2=top[b]; int ans=0; while(f1!=f2) { if(dep[f1]>dep[f2]) { ans=max(ans,query(1,1,n,w[f1],w[a])); a=fa[f1]; f1=top[a]; } else { ans=max(ans,query(1,1,n,w[f2],w[b])); b=fa[f2]; f2=top[b]; } } if(a==b) return ans; if(dep[a]>dep[b]) ans=max(ans,query(1,1,n,w[son[b]],w[a])); else ans=max(ans,query(1,1,n,w[son[a]],w[b])); return ans; } int main() { int cas,a,b,c; scanf("%d",&cas); while(cas--) { init(); scanf("%d",&n); for(int i=1; i<n; i++) { scanf("%d%d%d",&a,&b,&c); d[i][0]=a; d[i][1]=b; d[i][2]=c; add(a,b); add(b,a); } dfs(1); getid(1,1); for(int i=1; i<n; i++) { if(dep[d[i][0]]>dep[d[i][1]]) swap(d[i][0],d[i][1]); //把边权放到儿子节点,变成点权 update(1,1,n,w[d[i][1]],d[i][2]); } while(1) { scanf("%s",str); if(str[0]=='D') break; scanf("%d%d",&a,&b); if(str[0]=='Q') { printf("%d\n",find(a,b)); } else { update(1,1,n,w[d[a][1]],b); } } } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。