zoukankan      html  css  js  c++  java
  • SPOJ 375 Query on a tree【树链剖分】

    题目大意:给你一棵树,有两个操作1.修改一条边的值,2.询问从x到y路径上边的最大值

    思路:如果树退化成一条链的话线段树就很明显了,然后这题就是套了个树连剖分,调了很久终于调出来第一个模板了

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #define maxn 100009
      5 using namespace std;
      6 int head[maxn],next[maxn*2],point[maxn],son[maxn],size_k[maxn],id[maxn],value[maxn],now=0,father[maxn],top[maxn];
      7 int x[maxn],y[maxn],v[maxn],tree[maxn*4],pos=0,deep[maxn],n;
      8 int read()
      9 {
     10     int x=0,f=1;char ch=getchar();
     11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     13     return x*f;
     14 }
     15 void add(int x,int y,int v)
     16 {
     17     next[++now]=head[x];head[x]=now;
     18     point[now]=y;value[now]=v;
     19 }
     20 int dfs(int k,int fa)
     21 {
     22     deep[k]=deep[fa]+1;
     23     father[k]=fa;
     24     size_k[k]=1;
     25     int max_x=-1;
     26     son[k]=-1;
     27     for(int i=head[k];i;i=next[i])
     28     {
     29         if(point[i]==fa)continue;
     30         dfs(point[i],k);
     31         size_k[k]+=size_k[point[i]];
     32         if(size_k[point[i]]>max_x)
     33         {
     34                         max_x=size_k[point[i]];
     35             son[k]=point[i];
     36         }
     37     }
     38 }
     39 void dfs2(int k,int fa,int pa)
     40 {
     41     id[k]=++pos;
     42     top[k]=pa;
     43     if(son[k]!=-1)dfs2(son[k],k,pa);
     44     for(int i=head[k];i;i=next[i])
     45     {
     46         if(point[i]!=fa && point[i]!=son[k])dfs2(point[i],k,point[i]);
     47     }
     48 }
     49 void update(int node,int l,int r,int pos,int x)
     50 {
     51     if(l+1==r){tree[node]=x;return;}
     52     int mid=(l+r)>>1;
     53     if(pos<mid)update(node*2,l,mid,pos,x);
     54     else update(node*2+1,mid,r,pos,x);
     55     tree[node]=max(tree[node*2],tree[node*2+1]);
     56 }
     57 int query(int node,int l,int r,int ql,int qr)
     58 {
     59     if(ql<=l && r<=qr)return tree[node];
     60     int mid=(l+r)>>1;
     61     int ans=-0x3f3f3f3f;
     62     if(ql<mid)ans=max(query(node<<1,l,mid,ql,qr),ans);
     63     if(mid<qr)ans=max(query(node<<1|1,mid,r,ql,qr),ans);
     64     return ans;
     65 }
     66 int find(int x,int y)
     67 {
     68     int fa=top[x],fb=top[y],temp=0;
     69     while(fa!=fb)
     70     {
     71         if(deep[fa]<deep[fb])
     72         {
     73             swap(fa,fb);
     74             swap(x,y);
     75         }
     76         if(id[fa]>id[x]+1)return -1;
     77         temp=max(temp,query(1,1,pos+1,id[fa],id[x]+1));
     78         x=father[fa];fa=top[x];
     79     }
     80     if(x==y)return temp;
     81     if(deep[x]<deep[y])swap(x,y);
     82     if(id[y]+1>id[x]+1)return -1;
     83     return max(temp,query(1,1,pos+1,id[son[y]],id[x]+1));
     84 }
     85 int main()
     86 {
     87     int t;
     88     t=read();
     89     while(t--)
     90     {
     91         now=0;
     92         memset(head,0,sizeof(head));
     93         memset(tree,0,sizeof(tree));
     94         n=read();
     95         for(int i=1;i<n;i++)
     96         {
     97             x[i]=read();y[i]=read();v[i]=read();
     98             add(x[i],y[i],v[i]);
     99             add(y[i],x[i],v[i]);
    100         }
    101         deep[1]=0;
    102         dfs(1,0);
    103         dfs2(1,1,1);
    104         for(int i=1;i<=n-1;i++)
    105         {
    106             int u=deep[x[i]]>deep[y[i]]?x[i]:y[i];
    107             update(1,1,pos+1,id[u],v[i]);
    108         }
    109                 int xx,yy;
    110         char ch[100];
    111         while(true)
    112         {
    113             scanf("%s",ch);
    114             if(ch[0]=='D')break;
    115             xx=read();yy=read();
    116             if(ch[0]=='Q')
    117             {
    118                 printf("%d
    ",find(xx,yy));
    119             }
    120             else if(ch[0]=='C')
    121             {
    122                 int u=deep[x[xx]]>deep[y[xx]]?x[xx]:y[xx];
    123                 update(1,1,pos+1,id[u],yy);
    124             }
    125             else if(ch[0]=='D')
    126             {
    127                                 break;
    128             }
    129         }
    130     }
    131     return 0;
    132 }
  • 相关阅读:
    rsync备份服务
    Linux命令行基础及基础命令
    Linux重要目录及文件
    shell编程基础
    学习与生活
    从0开始使用python flask编写博客网站(2)
    python 七牛云图床的使用
    从0开始使用python flask编写博客网站(1)
    如何学习编程 我的编程学习之路
    Pyqt5 基本布局方式
  • 原文地址:https://www.cnblogs.com/philippica/p/4340096.html
Copyright © 2011-2022 走看看