SP375 QTREE - Query on a tree
Posted qyj060604
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SP375 QTREE - Query on a tree相关的知识,希望对你有一定的参考价值。
SP375 QTREE - Query on a tree
我是借这道题来说说如何从c++改到c的
1.我怕麻烦,所以把结构体拆了(忍痛割爱我封装的线段树)
2.max、swap函数进行了手写
max:
ll llmax(ll x,ll y)return x>y?x:y;
swap:
x^=y^=x^=y
emm...这的确是一个神奇的swap,不用函数
至于为什么是对的用人类智慧法即可
c++代码:(线段树封装)
#include<bits/stdc++.h> using namespace std; const int N=100005; typedef long long ll; struct line int from,to; ll val; int conec; s[N]; int n; int hed[N],tal[N<<1],nxt[N<<1],cnt=0; ll val[N<<1]; int fa[N]; int dep[N]; int size[N]=0; int son[N]=0; int dfn[N]; int rk[N]; int indexy=0; int top[N]; ll v[N]; ll llmax(ll x,ll y)return x>y?x:y; struct Sugment_Tree ll t[N<<2]; #define mid (l+r)/2 void push_up(int num) t[num]=llmax(t[num<<1],t[num<<1|1]); void build(int l,int r,int num) if(l==r) t[num]=v[l]; return; build(l,mid,num<<1),build(mid+1,r,num<<1|1); push_up(num); void upd(int l,int r,int num,int pos,ll SUM) if(l>pos||r<pos) return; if(l==r&&r==pos) t[num]=SUM; return; upd(l,mid,num<<1,pos,SUM); upd(mid+1,r,num<<1|1,pos,SUM); push_up(num); ll ask(int l,int r,int num,int L,int R) if(l>R||r<L) return 0; if(l>=L&&r<=R) return t[num]; return llmax(ask(l,mid,num<<1,L,R),ask(mid+1,r,num<<1|1,L,R)); T; void addege(int x,int y,ll z) cnt++; tal[cnt]=y; val[cnt]=z; nxt[cnt]=hed[x]; hed[x]=cnt; void dfs1(int u,int pa) fa[u]=pa; size[u]=1; for(int i=hed[u];i;i=nxt[i]) int v=tal[i]; if(v==fa[u]) continue; dep[v]=dep[u]+1; dfs1(v,u); size[u]+=size[v]; if(size[v]>size[son[u]]) son[u]=v; void dfs2(int u,int tp) indexy++; dfn[u]=indexy; rk[dfn[u]]=u; top[u]=tp; if(!son[u]) return; dfs2(son[u],tp); for(int i=hed[u];i;i=nxt[i]) int v=tal[i]; if(v==fa[u]||v==son[u]) continue; dfs2(v,v); ll cgn(int x,int y) ll ans=0; //LCA不能算进来!!!!!! while(top[x]!=top[y]) if(dep[top[x]]<dep[top[y]]) swap(x,y); ans=llmax(ans,T.ask(1,n,1,dfn[top[x]],dfn[x])); x=fa[top[x]]; if(dep[x]<dep[y]) swap(x,y); ans=llmax(ans,T.ask(1,n,1,dfn[y]+1,dfn[x])); return ans; int main() scanf("%d",&n); for(int i=1;i<n;i++) scanf("%d%d%lld",&s[i].from,&s[i].to,&s[i].val); addege(s[i].from,s[i].to,s[i].val); addege(s[i].to,s[i].from,s[i].val); dep[1]=1; dfs1(1,1); dfs2(1,1); for(int i=1;i<n;i++) if(fa[s[i].from]==s[i].to) v[dfn[s[i].from]]=s[i].val,s[i].conec=dfn[s[i].from]; else v[dfn[s[i].to]]=s[i].val,s[i].conec=dfn[s[i].to]; /* for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<endl; */ T.build(1,n,1); char c[10]; while(1) scanf("%s",c); if(c[0]==‘D‘) break; else if(c[0]==‘Q‘) int x,y; scanf("%d%d",&x,&y); if(x==y) printf("0\n"); continue; printf("%lld\n",cgn(x,y)); else int pos; ll va; scanf("%d%lld",&pos,&va); T.upd(1,n,1,s[pos].conec,va); return 0;
c:
#include <ctype.h> #include <stdio.h> #include <limits.h> #include <stdlib.h> #define N 100005 typedef long long ll; int from_P[N]; int to_P[N]; ll val_P[N]; int conec_P[N]; int n; int hed[N],tal[N<<1],nxt[N<<1],cnt=0; ll val[N<<1]; int fa[N]; int dep[N]; int size[N]=0; int son[N]=0; int dfn[N]; int rk[N]; int indexy=0; int top[N]; ll v[N]; int TE; ll llmax(ll x,ll y)return x>y?x:y; ll t[N<<2]; #define mid (l+r)/2 void push_up(int num) t[num]=llmax(t[num<<1],t[num<<1|1]); void build(int l,int r,int num) if(l==r) t[num]=v[l]; return; build(l,mid,num<<1),build(mid+1,r,num<<1|1); push_up(num); void upd(int l,int r,int num,int pos,ll SUM) if(l>pos||r<pos) return; if(l==r&&r==pos) t[num]=SUM; return; upd(l,mid,num<<1,pos,SUM); upd(mid+1,r,num<<1|1,pos,SUM); push_up(num); ll ask(int l,int r,int num,int L,int R) if(l>R||r<L) return 0; if(l>=L&&r<=R) return t[num]; return llmax(ask(l,mid,num<<1,L,R),ask(mid+1,r,num<<1|1,L,R)); void addege(int x,int y,ll z) cnt++; tal[cnt]=y; val[cnt]=z; nxt[cnt]=hed[x]; hed[x]=cnt; void dfs1(int u,int pa) fa[u]=pa; size[u]=1; for(int i=hed[u];i;i=nxt[i]) int v=tal[i]; if(v==fa[u]) continue; dep[v]=dep[u]+1; dfs1(v,u); size[u]+=size[v]; if(size[v]>size[son[u]]) son[u]=v; void dfs2(int u,int tp) indexy++; dfn[u]=indexy; rk[dfn[u]]=u; top[u]=tp; if(!son[u]) return; dfs2(son[u],tp); for(int i=hed[u];i;i=nxt[i]) int v=tal[i]; if(v==fa[u]||v==son[u]) continue; dfs2(v,v); ll cgn(int x,int y) ll ans=0; //LCA不能算进来!!!!!! while(top[x]!=top[y]) if(dep[top[x]]<dep[top[y]]) x^=y^=x^=y; ans=llmax(ans,ask(1,n,1,dfn[top[x]],dfn[x])); x=fa[top[x]]; if(dep[x]<dep[y]) x^=y^=x^=y; ans=llmax(ans,ask(1,n,1,dfn[y]+1,dfn[x])); return ans; int main() scanf("%d",&TE); while(TE--) cnt=0; indexy=0; for(int i=0;i<N;i++) hed[i]=0; for(int i=0;i<N;i++) dep[i]=0; for(int i=0;i<N;i++) size[i]=0; for(int i=0;i<N;i++) son[i]=0; scanf("%d",&n); for(int i=1;i<n;i++) scanf("%d%d%lld",&from_P[i],&to_P[i],&val_P[i]); addege(from_P[i],to_P[i],val_P[i]); addege(to_P[i],from_P[i],val_P[i]); dep[1]=1; dfs1(1,1); dfs2(1,1); for(int i=1;i<n;i++) if(fa[from_P[i]]==to_P[i]) v[dfn[from_P[i]]]=val_P[i],conec_P[i]=dfn[from_P[i]]; else v[dfn[to_P[i]]]=val_P[i],conec_P[i]=dfn[to_P[i]]; /* for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<endl; */ build(1,n,1); char c[10]; while(1) scanf("%s",c); if(c[0]==‘D‘) break; else if(c[0]==‘Q‘) int x,y; scanf("%d%d",&x,&y); if(x==y) printf("0\n"); continue; printf("%lld\n",cgn(x,y)); else int pos; ll va; scanf("%d%lld",&pos,&va); upd(1,n,1,conec_P[pos],va); return 0;
以上是关于SP375 QTREE - Query on a tree的主要内容,如果未能解决你的问题,请参考以下文章
SP375 QTREE - Query on a tree (树剖)
spoj375 QTREE - Query on a tree
[spoj 375]QTREE - Query on a tree[树链剖分]
SP913 QTREE2 - Query on a tree II