zoukankan      html  css  js  c++  java
  • spoj 375 query on a tree 题解

    题目大意:维护一棵树,支持查询两点间路径最大值,以及修改某边的权值。

    裸的树链剖分+线段树。。不多说

    这题卡常数卡的厉害啊!vector完全过不了

    然后。。我就写了我一点都不熟悉的普通邻接表。

    虽然代码丑,虽然依然很慢,虽然有点长,但是它至少A了。。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<vector>
      5 const int INF=~0U>>1;
      6 const int MAXN=10000+10;
      7 struct Edge{
      8     int u,v,cost;
      9     Edge() {}
     10     Edge(int u,int v,int cost):u(u),v(v),cost(cost) {}
     11 }edges[MAXN<<1];
     12 //std::vector<Edge> G[MAXN];
     13 int son[MAXN],dep[MAXN],w[MAXN],fa[MAXN],top[MAXN],sz[MAXN];
     14 int head[MAXN<<1],next[MAXN<<1];
     15 int dfs_clock;
     16 int n;
     17 inline void addedge(int u,int v,int cost,int edge)
     18 {
     19     edges[edge]=Edge(u,v,cost);
     20     next[edge]=head[u];
     21     head[u]=edge;
     22 }
     23 void dfs(int u)
     24 {
     25     sz[u]=1;son[u]=-1;
     26     for(int i=head[u];~i;i=next[i]) if(edges[i].v!=fa[u])
     27     {
     28         int v=edges[i].v;
     29         fa[v]=u;
     30         dep[v]=dep[u]+1;
     31         dfs(v);
     32         if(son[u]==-1 || sz[v]>sz[son[u]]) son[u]=v;
     33         sz[u]+=sz[v];
     34     }
     35 }
     36 void dfs2(int u,int tp)
     37 {
     38     w[u]=++dfs_clock;top[u]=tp;
     39     if(~son[u]) dfs2(son[u],tp);
     40     for(int i=head[u];~i;i=next[i]) if(edges[i].v!=fa[u] && edges[i].v!=son[u])
     41         dfs2(edges[i].v,edges[i].v);
     42 }
     43 int maxv[(1<<14)+10];
     44 int totn;
     45 void maintain(int o)
     46 {
     47     maxv[o]=std::max(maxv[o<<1],maxv[o<<1|1]);
     48 }
     49 void build(int o,int l,int r)
     50 {
     51     if(l==r) return;
     52     int m=l+r>>1;
     53     build(o<<1,l,m);
     54     build(o<<1|1,m+1,r);
     55     maxv[o]=std::max(maxv[o<<1],maxv[o<<1|1]);
     56 }
     57 int ask(int o,int l,int r,int x1,int x2)
     58 {
     59     if(r<x1 || l>x2) return -1;
     60     if(l>=x1 && r<=x2) return maxv[o];
     61     int m=l+r>>1;
     62     return std::max(ask(o<<1,l,m,x1,x2),ask(o<<1|1,m+1,r,x1,x2));
     63 }
     64 void update(int o,int l,int r,int x,int a)
     65 {
     66     if(l==r) maxv[o]=a;
     67     else
     68     {
     69         int m=l+r>>1;
     70         if(x<=m) update(o<<1,l,m,x,a);
     71         else update(o<<1|1,m+1,r,x,a);
     72         maintain(o);
     73     }
     74 }
     75 void init()
     76 {
     77     //memset(sz,0,sizeof(sz));
     78     //memset(maxv,-1,sizeof(maxv));
     79     memset(head,-1,sizeof(head));
     80     for(int i=0;i<=n;++i) sz[i]=0;
     81     dep[0]=0;
     82     dfs_clock=0;
     83     fa[0]=-1;
     84     int k=0;
     85     while((1<<k)<n) ++k;
     86     totn=1<<k;
     87     for(int i=0;i<=(totn<<1);++i) maxv[i]=-1;
     88 }
     89 int query(int u,int v)
     90 {
     91     int f1=top[u],f2=top[v],ans=-1;
     92     while(f1!=f2)
     93     {
     94         if(dep[f1]<dep[f2])
     95             std::swap(f1,f2),std::swap(u,v);
     96         ans=std::max(ans,ask(1,1,totn,w[f1],w[u]));
     97         u=fa[f1];f1=top[u];
     98     }
     99     if(u==v) return ans;
    100     if(dep[u]<dep[v]) std::swap(u,v);
    101     return std::max(ans,ask(1,1,totn,w[son[v]],w[u]));
    102 }
    103 int main()
    104 {
    105 //    freopen("1.in","r",stdin);
    106     int T;
    107     scanf("%d",&T);
    108     while(T--)
    109     {
    110         scanf("%d",&n);
    111         init();
    112         for(int i=0;i<n-1;++i)
    113         {
    114             int u,v,cost;
    115             scanf("%d%d%d",&u,&v,&cost);
    116             --u;--v;
    117             addedge(u,v,cost,i<<1);
    118             addedge(v,u,cost,i<<1|1);
    119         }
    120         dfs(0);
    121         dfs2(0,0);
    122         for(int i=0;i<n-1;++i)
    123         {
    124             int u=edges[i<<1].u,v=edges[i<<1].v;
    125             if(dep[u]>dep[v]) std::swap(u,v);
    126             update(1,1,totn,w[v],edges[i<<1].cost);
    127         }
    128         char s[10];
    129         while(scanf("%s",s)==1 && s[0]!='D')
    130         {
    131             if(s[0]=='Q')
    132             {
    133                 int u,v;
    134                 scanf("%d%d",&u,&v);
    135                 --u;--v;
    136                 printf("%d\n",query(u,v));
    137             }
    138             else
    139             {
    140                 int x,a;
    141                 scanf("%d%d",&x,&a);
    142                 --x;
    143                 int u=edges[x<<1].u,v=edges[x<<1].v;
    144                 if(dep[u]>dep[v]) std::swap(u,v);
    145                 update(1,1,totn,w[v],a);
    146             }
    147         }
    148     }
    149     return 0;
    150 }
    View Code
  • 相关阅读:
    mongoDB看这篇就够了
    放不下
    jmeter连接不上MySQL数据库的原因以及解决方法
    SecureCRT自动断开连接的解决方法
    Linux及Windows查看占用端口的进程
    网络基础知识
    selenium中driver.close()和driver.quit()的不同点
    day2_窗口句柄切换
    day6_异常捕捉
    day6_logging模块
  • 原文地址:https://www.cnblogs.com/lowsfish/p/4335649.html
Copyright © 2011-2022 走看看