SPOJ375 Query on a tree经典入门题
剖分边更新,线段树点更新区间求极值。学树链剖分感觉还是先做点更新的好,而不是边更新。其实最主要还用来维护的数据结构了,剖分基本上都成模板了。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 #define lson l,m,rt<<1 6 #define rson m+1,r,rt<<1|1 7 const int maxn = 10005; 8 const int INF = 0x3f3f3f3f; 9 int n; 10 int siz[maxn],fa[maxn],son[maxn],dep[maxn]; 11 int top[maxn],tid[maxn],lable; 12 int head[maxn],cnt; 13 struct edge 14 { 15 int v,w,en,next; 16 }e[maxn*2]; 17 int sum[maxn<<2]; 18 void init() 19 { 20 memset(head,-1,sizeof(head)); 21 cnt = lable = 0; 22 } 23 void add(int u,int v,int w) 24 { 25 e[cnt].v = v; 26 e[cnt].w = w; 27 e[cnt].next = head[u]; 28 head[u] = cnt++; 29 } 30 void find_heavy(int rt,int father,int depth) 31 { 32 fa[rt] = father; 33 son[rt] = 0; 34 siz[rt] = 1; 35 dep[rt] = depth; 36 int maxsize = 0; 37 for(int i = head[rt];i!=-1;i = e[i].next)if(e[i].v!=father) 38 { 39 e[i].en = e[i^1].en = e[i].v; 40 find_heavy(e[i].v,rt,depth+1); 41 siz[rt]+=siz[e[i].v]; 42 if(siz[e[i].v]>maxsize) 43 maxsize = siz[e[i].v],son[rt] = e[i].v; 44 } 45 } 46 void pushup(int rt) 47 { 48 sum[rt] = max(sum[rt<<1],sum[rt<<1|1]); 49 } 50 void update(int pos ,int val,int l,int r,int rt) 51 { 52 if(l==r){ 53 sum[rt] = val; 54 return; 55 } 56 int m = (l+r)>>1; 57 if(pos<=m)update(pos,val,lson); 58 else update(pos,val,rson); 59 pushup(rt); 60 } 61 void connect(int rt,int anc) 62 { 63 tid[rt] = ++lable; 64 top[rt] = anc; 65 if(son[rt])connect(son[rt],anc); 66 for(int i= head[rt];i!=-1;i = e[i].next) 67 if(e[i].v!=fa[rt]&&e[i].v!=son[rt]) 68 connect(e[i].v,e[i].v); 69 } 70 int query(int L,int R,int l,int r,int rt) 71 { 72 if(L<=l&&r<=R)return sum[rt]; 73 int m = (l+r)>>1,ret = -INF; 74 if(L<=m)ret = max(ret,query(L,R,lson)); 75 if(m<R)ret = max(ret,query(L,R,rson)); 76 return ret; 77 } 78 int getmax(int x,int y) 79 { 80 int ans = -INF; 81 while(top[x]!=top[y]) 82 { 83 if(dep[top[x]]<dep[top[y]])swap(x,y); 84 ans = max(ans,query(tid[top[x]],tid[x],1,n,1)); 85 x = fa[top[x]]; 86 } 87 if(x==y)return ans; 88 if(dep[x]>dep[y])swap(x,y); 89 ans = max(ans,query(tid[son[x]],tid[y],1,n,1)); 90 return ans; 91 } 92 int main() 93 { 94 // freopen("out.txt","r",stdin); 95 int T;scanf("%d",&T); 96 while(T--) 97 { 98 scanf("%d",&n); 99 init(); 100 for(int i = 1;i<n;++i) 101 { 102 int u,v,w; 103 scanf("%d%d%d",&u,&v,&w); 104 add(u,v,w); 105 add(v,u,w); 106 } 107 find_heavy(1,1,1); 108 connect(1,1); 109 110 for(int i = 0;i<cnt;i+=2)update(tid[e[i].en],e[i].w,1,n,1); 111 update(1,0,1,n,1); 112 while(1) 113 { 114 char s[10];scanf("%s",s); 115 if(s[0]=='D')break; 116 int u,v; 117 scanf("%d%d",&u,&v); 118 if(s[0]=='Q')printf("%d\n",getmax(u,v)); 119 else update(tid[e[u*2-1].en],v,1,n,1); 120 } 121 } 122 return 0; 123 }
弱者究竟为何而战?!