spoj375 树链剖分模板(边权,点修改求区间最大值)

  1 #include<stdio.h>
  2 #include<string.h>
  3 int now,cnt,d[100005][5];
  4 int next[100005],head[100005],point[100005];
  5 int son[100005],father[100005],num[100005],deep[100005];
  6 int pre[100005],tree[100005],top[100005];
  7 int maxv[100005];
  8 int max(int x,int y)
  9 {
 10     if (x>y) return x;
 11     return y;
 12 }
 13 void add(int x,int y,int w)
 14 {
 15     next[++now]=head[x];
 16     head[x]=now;
 17     point[now]=y;
 18 }
 19 void dfs1(int u)
 20 {
 21     num[u]=1;
 22     for (int i=head[u];i!=-1;i=next[i])
 23     {
 24         int v=point[i];
 25         if (v==father[u]) continue;
 26         father[v]=u; deep[v]=deep[u]+1;
 27         dfs1(v);
 28         num[u]+=num[v];
 29         if (son[u]==-1||num[son[u]]<num[v]) son[u]=v;
 30     }
 31 }
 32 void dfs2(int u,int lead)
 33 {
 34     top[u]=lead;
 35     tree[u]=++cnt;
 36     pre[cnt]=u;
 37     if (son[u]==-1) return;
 38     dfs2(son[u],lead);
 39     for (int i=head[u];i!=-1;i=next[i])
 40     {
 41         int v=point[i];
 42         if (son[u]!=v&&father[u]!=v) dfs2(v,v);
 43     }
 44 }
 45 void update(int o,int l,int r,int y,int dd)
 46 {
 47     if (y>r||y<l) return;
 48     if (l==r) { maxv[o]=dd; return; }
 49     else{
 50         int mid=l+(r-l)/2;
 51         if (y<=mid) update(o*2,l,mid,y,dd);
 52         if (y>mid) update(o*2+1,mid+1,r,y,dd);
 53         maxv[o]=max(maxv[o*2],maxv[o*2+1]);
 54     }
 55 }
 56 int query(int o,int l,int r,int ql,int qr)
 57 {
 58     int mid=l+(r-l)/2,temp=0;
 59     if (ql<=l&&qr>=r) return maxv[o];
 60     if (ql<=mid) temp=query(o*2,l,mid,ql,qr);
 61     if (qr>mid) temp=max(temp,query(o*2+1,mid+1,r,ql,qr));
 62     return temp;
 63 }
 64 int change(int l,int r)
 65 {
 66     int temp,mm=0;
 67     while (top[l]!=top[r])
 68     {
 69         if (deep[top[l]]<deep[top[r]]) {temp=l; l=r; r=temp; }
 70         mm=max(mm,query(1,1,cnt,tree[top[l]],tree[l]));
 71         l=father[top[l]];
 72     }
 73     if (deep[l]>deep[r]) {temp=l; l=r; r=temp; }
 74     mm=max(mm,query(1,1,cnt,tree[son[l]],tree[r]));//边一定要注意这时改重链根的儿子所对应的父边
 75     return mm;
 76 }
 77 int main()
 78 {
 79     int T,n,i,temp,x,y;
 80     char s[15];
 81     scanf("%d",&T);
 82     while (T--)
 83     {
 84         scanf("%d",&n);
 85         memset(head,-1,sizeof(head));
 86         memset(son,-1,sizeof(son));
 87         deep[1]=0;  father[1]=1;
 88         now=cnt=0;
 89         for (i=1;i<n;i++)
 90         {
 91             scanf("%d%d%d",&d[i][0],&d[i][1],&d[i][2]);
 92             add(d[i][0],d[i][1],d[i][2]);
 93             add(d[i][1],d[i][0],d[i][1]);
 94         }
 95         dfs1(1); dfs2(1,1);
 96         memset(maxv,0,sizeof(maxv));
 97         for (i=1;i<n;i++)
 98         {
 99             if (deep[d[i][0]]>deep[d[i][1]]) {temp=d[i][0]; d[i][0]=d[i][1]; d[i][1]=temp; }
100             update(1,1,cnt,tree[d[i][1]],d[i][2]);
101         }
102         while (1)
103         {
104             scanf("%s",s);
105             if (s[0]=='D') break;
106             scanf("%d%d",&x,&y);
107             if (s[0]=='Q') printf("%d\n",change(x,y));
108             else update(1,1,cnt,tree[d[x][1]],y);
109         }
110     }
111     return 0;
112 }

http://www.spoj.com/problems/QTREE/

posted on 2014-10-01 23:41  xiao_xin  阅读(151)  评论(0编辑  收藏  举报

导航