spoj375树链剖分模板

来源:互联网 发布:淘宝客推广计划 编辑:程序博客网 时间:2024/04/30 00:47

题意:

    对于一颗树,两种操作(1)修改某边权(2)查询两点间最大边权

解:树链剖分

代码(200ms):

#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<vector>#include<ctime>#include<queue>#define For(i,j,k) for(register int i=(j);i<=(int)k;i++)#define Forr(i,j,k) for(register int i=(j);i>=(int)k;i--)#define Rep(i,u) for(register int i=Begin[(u)],v=to[i];i;i=Next[i],v=to[i])#define Set(a,b) memset((a),b,sizeof(a))using namespace std;const int N=10010,E=20010;int Begin[N],Next[E],to[E],fa[N],siz[N],son[N],dep[N],w[N],e=1,top[N],cnt,n;int d[N][3];void read(int &x){x=0;char c=getchar();int f(0);while(c<'0'||c>'9'){c=getchar();if(c=='-')f=1;}while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();if(f)x=-x;}inline void add(int x,int y){to[++e]=y,Next[e]=Begin[x],Begin[x]=e;}struct zkwtree{int T[N<<2],M;inline void clear(){Set(T,0);}inline void pushup(int x){T[x]=max(T[x<<1],T[x<<1|1]);}void Build(){for(M=1;M<=n+1;M<<=1);}void add(int x,int v){for(T[x+=M]=v,x>>=1;x;x>>=1)pushup(x);}int query(int s,int t){int ret=-0x3f3f3f3f;for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){if(~s&1)ret=max(ret,T[s^1]);if(t&1)ret=max(ret,T[t^1]);}return ret;}}t;void dfs1(int u,int d){siz[u]=1;dep[u]=d;Rep(i,u)if(fa[u]!=v){fa[v]=u,dfs1(v,d+1),siz[u]+=siz[v];if(siz[v]>siz[son[u]])son[u]=v;}} void dfs2(int u,int tp){top[u]=tp,w[u]=++cnt;if(son[u])dfs2(son[u],top[u]);Rep(i,u)if(son[u]!=v&&fa[u]!=v)dfs2(v,v);}void init(){read(n);Set(son,0),Set(Begin,0),Set(fa,0),e=1,cnt=0;For(i,1,n-1){read(d[i][0]),read(d[i][1]),read(d[i][2]);add(d[i][0],d[i][1]),add(d[i][1],d[i][0]);}dfs1(1,1);dfs2(1,1);t.clear();t.Build();For(i,1,n-1){if(dep[d[i][0]]>dep[d[i][1]])swap(d[i][0],d[i][1]);t.add(w[d[i][1]],d[i][2]);}}int Max(int x,int y){int tmp=-0x3f3f3f3f;for(;top[x]!=top[y];){if(dep[top[x]]<dep[top[y]])swap(x,y);tmp=max(tmp,t.query(w[top[x]],w[x]));x=fa[top[x]];}if (x==y)return tmp;if (dep[x]>dep[y])swap(x,y);return max(tmp,t.query(w[x]+1,w[y]));}void solve(){char s[10];while(scanf("%s",s)!=EOF){int x,y;if (s[0]=='D')break;read(x),read(y);if (s[0]!='Q')t.add(w[d[x][1]],y);else printf("%d\n",Max(x,y));}}int main(){int _;for(read(_);_;_--){init();solve();}return 0;} 


0 0