Welcome, Guest! Sign Up RSS

Clever Space

Friday, 11.22.2024
Main » 2013 » November » 21 » 树链剖分T2—SPOJ QTREE
4:17 PM
树链剖分T2—SPOJ QTREE

这道题比起DISQUERY来就是用线段树上加一个修改了,

其他部分一样,注意边的序号跟踪

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<set>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<iostream>
#include<string>
#include<cmath>
#define N 20010
#define lc(x) (x<<1)
#define rc(x) ((x<<1)+1)
#define FOR(i,a,b) for(i=(a);i<=(b);i++)
#define ROF(i,a,b) for(i=(a);i>=(b);i--)
typedef long long LL;
using namespace std;
struct node{int l,r,Max;};
int last[N],pre[N],e[N],W[N],idx[N];
int w[N],pos[N],siz[N],son[N],fa[N],dep[N],top[N],b[N];
int a[N];char OP[101];
int t1,t2,t3,n,q,len=0,size=0;
void add(int x,int y,int z,int ID)
{pre[++len]=last[x];last[x]=len;e[len]=y;W[len]=z;idx[len]=ID;}
int swap(int &x,int &y){int t=x;x=y;y=t;}
struct segtree
{
  node tree[4*N];
  void init(){memset(tree,0,sizeof(tree));}
  void update(int x){tree[x].Max=max(tree[lc(x)].Max,tree[rc(x)].Max);} 
  void build(int x,int L,int R)
  {
    tree[x].l=L;tree[x].r=R;int mid=(L+R)>>1;
    if (L==R) {tree[x].Max=a[L];return;}
    build(lc(x),L,mid);build(rc(x),mid+1,R);
    update(x);
  }
  int query(int x,int L,int R)
  {
    if (tree[x].l==L&&tree[x].r==R) return tree[x].Max;
    int mid=(tree[x].l+tree[x].r)>>1;
    if (R<=mid) return query(lc(x),L,R);
    if (L>mid) return query(rc(x),L,R);
    return max(query(lc(x),L,mid),query(rc(x),mid+1,R));
  }
  void modify(int x,int p,int ti)
  {
    if (tree[x].l==tree[x].r) {tree[x].Max=ti;return;}
    int mid=(tree[x].l+tree[x].r)>>1;
    if (p<=mid) modify(lc(x),p,ti);
    else modify(rc(x),p,ti);
    update(x);
  }
}Tree;
void DFS1(int x,int par,int Dep)
{
  dep[x]=Dep;siz[x]=1;son[x]=0;
  for(int p=last[x];p;p=pre[p])
  {
    int v=e[p],ID=idx[p];
    if (par==v) continue;
    fa[v]=x;b[v]=W[p];pos[ID]=v;
    DFS1(v,x,Dep+1);
    if (son[x]==0||siz[v]>siz[son[x]]) son[x]=v;
    siz[x]+=siz[v];
  }
}
void DFS2(int x,int Top)
{
  w[x]=++size;top[x]=Top;    
  a[size]=b[x];
  if (son[x]!=0) DFS2(son[x],Top);
  for(int p=last[x];p;p=pre[p])
  {
    int v=e[p];
    if (v==fa[x]||v==son[x]) continue;
    DFS2(v,v);
  }
}
int getans(int va,int vb)
{
  int f1=top[va],f2=top[vb],tmp=-1e9;
  while (f1!=f2)
  {
    if (dep[f1]<dep[f2]){swap(f1,f2);swap(va,vb);}
    tmp=max(tmp,Tree.query(1,w[f1],w[va]));
    va=fa[f1];f1=top[va];
  }
  if (va==vb) return tmp;
  if (dep[va]>dep[vb]) swap(va,vb);
  return max(tmp,Tree.query(1,w[son[va]],w[vb]));
}
int Main()
{
  memset(pre,0,sizeof(pre));
  memset(last,0,sizeof(last)); 
  memset(idx,0,sizeof(idx));
  len=size=0;Tree.init();
  scanf("%d",&n);int i;
  FOR(i,1,n-1) 
  {
    scanf("%d%d%d",&t1,&t2,&t3);
    add(t1,t2,t3,i);add(t2,t1,t3,i);
  }
  DFS1(1,-1,1);
  DFS2(1,1);
  Tree.build(1,1,n);
  scanf("%s",OP);
  while (strcmp(OP,"DONE")!=0)
  {
    scanf("%d%d",&t1,&t2);
    if (strcmp(OP,"CHANGE")==0)
    {
      Tree.modify(1,w[pos[t1]],t2);
    }else
    {
      int ans=getans(t1,t2);
      printf("%d\n",ans);
    }
    scanf("%s",OP);
  }
}
int main()
{
  int T;
  scanf("%d",&T);
  while (T--) Main();
}
Views: 565 | Added by: dhy0077 | Rating: 5.0/1
Total comments: 0
Only registered users can add comments.
[ Sign Up | Login ]