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

 

posted @ 2015-03-13 17:29  lowsfish  阅读(165)  评论(0编辑  收藏  举报