打了快一星期的qtree终于打完了- - (其实还有两题改不出来弃疗了QAQ)
orz神AK一星期前就虐完QTREE
避免忘记还是简单写下题解吧0 0
题意:
给出一颗带边权树
一个操作:修改边权
还有一个询问:求x到y路径上边权最大值
树链剖分模版题- -blabla
代码:
1 #include <cstdio> 2 #include <cstring> 3 const int N=10001; 4 struct inli{ 5 int next,data,lon; 6 inli(const int a=0,const int b=0,const int c=0): 7 next(a),data(b),lon(c){} 8 }line[N*2]; 9 struct info{ 10 int x,y; 11 info(const int a=0,const int b=0): 12 x(a),y(b){} 13 }sline[N]; 14 int n,t,nl,dfss,back[N],tree[N*4],deep[N],num[N],hard[N],dfn[N],fl[N],fat[N],gr[N],son[N]; 15 int st,si; 16 char s[10]; 17 int max(int x,int y){ return x>y ? x : y; } 18 void swap(int &x,int &y){ int t=x; x=y,y=t; } 19 void clean(){ 20 nl=dfss=0; 21 memset(son,0,sizeof(son)); 22 memset(hard,0,sizeof(hard)); 23 memset(tree,0,sizeof(tree)); 24 } 25 void makehard(int t){ 26 num[t]=1; 27 for (int i=son[t];i;i=line[i].next) 28 if (line[i].data!=fat[t]){ 29 int ne=line[i].data; 30 fat[ne]=t; 31 deep[ne]=deep[t]+1; 32 fl[ne]=line[i].lon; 33 makehard(ne); 34 num[t]+=num[ne]; 35 if (num[hard[t]]<num[ne]) hard[t]=ne; 36 } 37 } 38 void dfs(int t,int gra){ 39 dfn[t]=++dfss; 40 back[dfss]=t; 41 gr[t]=gra; 42 if (hard[t]) dfs(hard[t],gra); 43 for (int i=son[t];i;i=line[i].next){ 44 int ne=line[i].data; 45 if (ne!=fat[t] && ne!=hard[t]) dfs(ne,ne); 46 } 47 } 48 void build(int l,int r,int rt){ 49 if (l==r-1){ 50 tree[rt]=fl[back[r]]; 51 return; 52 } 53 int mid=(l+r)/2; 54 build(l,mid,rt*2); 55 build(mid,r,rt*2+1); 56 tree[rt]=max(tree[rt*2],tree[rt*2+1]); 57 } 58 int getmax(int l,int r,int rt,int x,int y){ 59 if (x==y) return 0; 60 if (x<=l && r<=y) return tree[rt]; 61 int mid=(l+r)/2,res=0; 62 if (x<mid) res=max(res,getmax(l,mid,rt*2,x,y)); 63 if (mid<y) res=max(res,getmax(mid,r,rt*2+1,x,y)); 64 return res; 65 } 66 int getans(int x,int y){ 67 if (x==y) return 0; 68 if (gr[x]==gr[y]){ 69 if (deep[x]>deep[y]) swap(x,y); 70 return getmax(1,n,1,dfn[x],dfn[y]); 71 } 72 if (deep[gr[x]]<deep[gr[y]]) swap(x,y); 73 return max(getans(fat[gr[x]],y),max(getmax(1,n,1,dfn[gr[x]],dfn[x]),fl[gr[x]])); 74 } 75 void change2(int l,int r,int rt,int x,int y){ 76 if (l+1==r) return (void)(tree[rt]=y); 77 int mid=(l+r)/2; 78 if (x<mid) change2(l,mid,rt*2,x,y); 79 else change2(mid,r,rt*2+1,x,y); 80 tree[rt]=max(tree[rt*2],tree[rt*2+1]); 81 } 82 void change(int t,int s){ 83 int x=sline[t].x,y=sline[t].y; 84 if (deep[x]>deep[y]) swap(x,y); 85 if (gr[x]==gr[y]) change2(1,n,1,dfn[x],s); 86 else fl[y]=s; 87 } 88 int main(){ 89 freopen("spoj375.in","r",stdin); 90 freopen("spoj375.out","w",stdout); 91 for (scanf("%d",&t);t;t--){ 92 clean(); 93 scanf("%d\n",&n); 94 int x,y,z; 95 for (int i=1;i<n;i++){ 96 scanf("%d%d%d\n",&x,&y,&z); 97 line[++nl]=inli(son[x],y,z),son[x]=nl; 98 line[++nl]=inli(son[y],x,z),son[y]=nl; 99 sline[i]=info(x,y); 100 } 101 makehard(1); 102 dfs(1,1); 103 build(1,n,1); 104 int i=0; 105 while (1){ 106 si=++i; 107 st=t; 108 if (i==9995) 109 i=9995; 110 if (t==2) 111 t=2; 112 if (t==9 && i==9999) 113 t=9; 114 scanf("%s",s); 115 if (s[0]=='Q'){ 116 scanf("%d%d\n",&x,&y); 117 printf("%d\n",getans(x,y)); 118 } 119 if (s[0]=='C'){ 120 scanf("%d%d\n",&x,&y); 121 change(x,y); 122 } 123 if (s[0]=='D') break; 124 if (n==2) 125 n=2; 126 } 127 } 128 fclose(stdin); 129 fclose(stdout); 130 }