题目大意:维护一棵树,支持查询两点间路径最大值,以及修改某边的权值。
裸的树链剖分+线段树。。不多说
这题卡常数卡的厉害啊!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 }