打了快一星期的qtree终于打完了- - (其实还有两题改不出来弃疗了QAQ)

orz神AK一星期前就虐完QTREE

避免忘记还是简单写下题解吧0 0

 

QTREE1

题意:

给出一颗带边权树

一个操作:修改边权

还有一个询问:求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 }
View Code

相关文章: