赤裸裸的树链剖分,结果划分轻重边时以为同一条链的重边相邻。。。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
struct line
{
int x,y,z;
}p[30005];
int rt[10005],ro[10005],q[10005],g[10005],d[10005],w[10005],b[65536],u[10005],tail[10005],next[30005],sora[30005],cost[30005],v[10005],c[10005];
int power[30005],o[10005],l[10005],r[10005],a[15];
int f[50000][15];
int n,m,tot,t,tt,m1,ans,ss;
void dfs(int x,int y,int dep,int bj)
{
int i,ne,cos;
rt[x]=y;ro[x]=bj;q[bj]=x;g[x]=1;
f[++tot][0]=x;
d[x]=dep;u[x]=tot;
int maxg=0,maxi=0,maxb=0;
for (i=x;next[i]!=0;)
{
i=next[i];ne=sora[i];
if (ne!=y)
{
dfs(ne,x,dep+1,power[i]);
f[++tot][0]=x;
g[x]+=g[ne];
if (g[ne]>maxg)
{
maxg=g[ne];maxi=ne;maxb=cost[i];
}
}
}
if (0==maxg) return ;
ne=maxi;cos=maxb;
if (v[ne])
{
w[ne]=cos;
v[x]=v[ne];
}
else
{
w[ne]=cos;
++t;
v[x]=t,v[ne]=t;
}
}
int min(int x,int y)
{
return (d[x]<d[y]) ? x : y;
}
int max(int x,int y)
{
return (w[x]>w[y]) ? x : y;
}
void change(int x,int ww)
{
w[x]=ww;
x=(o[x]+m1)>>1;
for (;x;x>>=1) b[x]=max(b[x<<1],b[(x<<1)+1]);
}
int cmp(const void*i,const void*j)
{
int p=*(int *)i,q=*(int *)j;
if (v[p]!=v[q]) return v[p] - v[q];
return -(d[p]-d[q]);
}
void ori()
{
int k,i,j;
k=(int)floor(log2(tot));
a[0]=1;
for (i=1;i<=k;i++) a[i]=a[i-1]<<1;
for (i=1;i<=k;i++)
for (j=1;j<=tot;j++)
if (j+a[i]-1<=tot)
f[j][i]=min(f[j][i-1],f[j+a[i-1]][i-1]);
else break;
for (i=1;i<=n;i++) c[i]=i;
qsort(c+1,n,sizeof(c[1]),cmp);
for (i=1;i<=n;i++)
if (v[c[i]])
{
r[v[c[i]]]=i;
o[c[i]]=i;
b[i+m1]=c[i];
change(c[i],w[c[i]]);
}
}
int lca(int x,int y)
{
int e;
if (x>y) {e=x;x=y;y=e;}
int ans=0,k;
k=(int)floor(log2(y-x+1));
ans=min(f[x][k],f[y-a[k]+1][k]);
return ans;
}
int ask(int l,int r)
{
int ans=0;
l=l+m1-1,r=r+m1+1;
for (;!(1==(l^r));l>>=1,r>>=1)
{
if (0==(l&1)) if (w[b[l+1]]>ans) ans=w[b[l+1]];
if (1==(r&1)) if (w[b[r-1]]>ans) ans=w[b[r-1]];
}
return ans;
}
void make(int x,int ari)
{
int ll,rr,cos;
for (;x!=ari;)
{
if (v[x])
{
ll=o[x];
if (v[x]!=v[ari]) rr=r[v[x]]-1;
else rr=o[ari]-1;
cos=ask(ll,rr);
if (cos>ans) ans=cos;
if (v[x]==v[ari]) x=b[rr+m1];else x=b[rr+m1+1];
if (p[ro[x]].z>ans) ans=p[ro[x]].z;
x=rt[x];
}
else
{
if (p[ro[x]].z>ans) ans=p[ro[x]].z;
x=rt[x];
}
}
}
void origin()
{
int i;
m1=1;
for (;m1<=n+2;m1<<=1) ;
ss=n;
for (i=1;i<=n;i++) tail[i]=i;
}
void link(int x,int y,int z,int i)
{
ss++;next[tail[x]]=ss;tail[x]=ss;sora[ss]=y;cost[ss]=z;power[ss]=i;
}
void init()
{
int i,x,y,z,lcr;
char ch;
scanf("%d\n",&n);
origin();
for (i=1;i<=n-1;i++)
{
scanf("%d%d%d\n",&x,&y,&z);
link(x,y,z,i);link(y,x,z,i);
p[i].x=x,p[i].y=y,p[i].z=z;
}
t=0;tt=0;tot=0;
memset(d,127,sizeof(d));
dfs(1,0,1,0);
ori();
scanf("%d\n",&m);
for (i=1;i<=m;i++)
{
scanf("%c",&ch);
if ('Q'==ch)
{
scanf("%d%d\n",&x,&y);
ans=0,lcr=lca(u[x],u[y]);
make(x,lcr);
make(y,lcr);
printf("%d\n",ans);
}
else
{
scanf("%d%d\n",&x,&y);
p[x].z=y;
if (v[q[x]]) change(q[x],y);
}
}
}
int main()
{
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
init();
return 0;
}