「POJ3237」Tree(树链剖分)

题意

给棵n个点的树。边有边权然后有三种操作

1、CHANGE i v 将编号为i的边权变为v

2、NEGATE a b 将a到b的所有边权变为相反数。

3、QUERY a b 查询a b路径的最大边权。

(n,q<=10000)

题解

树剖裸题。

边权下放。线段树记录最大值最小值即可。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<algorithm>
  6 using namespace std;
  7 const int N=10010;
  8 int cnt,head[N];
  9 int size[N],fa[N],dep[N],ww[N],son[N],ide[N];
 10 int top[N],id[N],tot,w[N];
 11 int t,n;
 12 char s[100]; 
 13 struct edge{
 14     int to,nxt,w,id;
 15 }e[N*3];
 16 void add(int u,int v,int w,int id){
 17     cnt++;
 18     e[cnt].nxt=head[u];
 19     e[cnt].to=v;
 20     e[cnt].w=w;
 21     e[cnt].id=id;
 22     head[u]=cnt;
 23 }
 24 struct tree{
 25     int l,r,maxx,minn,lazy;
 26 }tr[N*8];
 27 void update(int now){
 28     tr[now].maxx=max(tr[now*2].maxx,tr[now*2+1].maxx);
 29     tr[now].minn=min(tr[now*2].minn,tr[now*2+1].minn);
 30 }
 31 void pushdown(int now){
 32     if(tr[now].lazy==0)return;
 33     int hh=tr[now*2].maxx;
 34     tr[now*2].maxx=-tr[now*2].minn;
 35     tr[now*2].minn=-hh;
 36     hh=tr[now*2+1].maxx;
 37     tr[now*2+1].maxx=-tr[now*2+1].minn;
 38     tr[now*2+1].minn=-hh;
 39     tr[now*2].lazy^=1;
 40     tr[now*2+1].lazy^=1;
 41     tr[now].lazy=0;
 42 }
 43 void dfs1(int u,int f,int deep){
 44     size[u]=1;
 45     fa[u]=f;
 46     dep[u]=deep;
 47     int maxson=-1;
 48     for(int i=head[u];i;i=e[i].nxt){
 49         int v=e[i].to;
 50         if(v==f)continue;
 51         ww[v]=e[i].w;
 52         ide[e[i].id]=v;
 53         dfs1(v,u,deep+1);
 54         size[u]+=size[v];
 55         if(size[v]>maxson){
 56             son[u]=v;
 57             maxson=size[v];
 58         }
 59     }
 60 }
 61 void dfs2(int u,int tp){
 62     top[u]=tp;
 63     id[u]=++tot;
 64     w[tot]=ww[u];
 65     if(!son[u])return;
 66     dfs2(son[u],tp);
 67     for(int i=head[u];i;i=e[i].nxt){
 68         int v=e[i].to;
 69         if(v==fa[u]||v==son[u])continue;
 70         dfs2(v,v);
 71     }
 72 } 
 73 void build(int l,int r,int now){
 74     tr[now].l=l;tr[now].r=r;
 75     tr[now].maxx=tr[now].lazy=tr[now].minn=0;
 76     if(l==r){
 77         tr[now].maxx=tr[now].minn=w[l];
 78         return;
 79     }
 80     int mid=(l+r)>>1;
 81     build(l,mid,now*2);
 82     build(mid+1,r,now*2+1);
 83     update(now);
 84 }
 85 int getmax(int l,int r,int now){
 86     pushdown(now); 
 87     if(tr[now].l==l&&tr[now].r==r){
 88         return tr[now].maxx;
 89     }
 90     int mid=(tr[now].l+tr[now].r)>>1;
 91     if(l>mid)return getmax(l,r,now*2+1);
 92     else if(r<=mid)return getmax(l,r,now*2);
 93     else {
 94         return max(getmax(l,mid,now*2),getmax(mid+1,r,now*2+1));
 95     }
 96 }
 97 void change(int x,int y,int now){
 98     pushdown(now);
 99     if(tr[now].l==tr[now].r){
100         tr[now].maxx=tr[now].minn=y;
101         return;
102     }
103     int mid=(tr[now].l+tr[now].r)>>1;
104     if(x>mid)change(x,y,now*2+1);
105     else if(x<=mid)change(x,y,now*2);
106     update(now); 
107 }
108 void getfan(int l,int r,int now){
109     pushdown(now);
110     if(tr[now].l==l&&tr[now].r==r){
111         tr[now].lazy^=1;
112         int hh=tr[now].maxx;
113         tr[now].maxx=-tr[now].minn;
114         tr[now].minn=-hh;
115         return;
116     }
117     int mid=(tr[now].l+tr[now].r)>>1;
118     if(l>mid)getfan(l,r,now*2+1);
119     else if(r<=mid)getfan(l,r,now*2);
120     else{
121         getfan(l,mid,now*2);
122         getfan(mid+1,r,now*2+1); 
123     } 
124     update(now);
125 }
126 int getlca(int x,int y){
127     while(top[x]!=top[y]){
128         if(dep[top[x]]<dep[top[y]])swap(x,y);
129         x=fa[top[x]];
130     }
131     if(dep[x]<dep[y])return x;
132     else return y;
133 }
134 int getmaxl(int x,int y){
135     int ans=-1999999999;
136     while(top[x]!=top[y]){
137         if(dep[top[x]]<dep[top[y]])swap(x,y);
138         ans=max(ans,getmax(id[top[x]],id[x],1));
139         x=fa[top[x]];
140     }
141     if(x==y)return ans;
142     if(dep[x]>dep[y])swap(x,y);
143     ans=max(ans,getmax(id[x]+1,id[y],1));
144     return ans;
145 }
146 void getfanl(int x,int y){
147     while(top[x]!=top[y]){
148         if(dep[top[x]]<dep[top[y]])swap(x,y);
149         getfan(id[top[x]],id[x],1);
150         x=fa[top[x]];
151     }
152     if(x==y)return;
153     if(dep[x]>dep[y])swap(x,y);
154     getfan(id[x]+1,id[y],1);
155 }
156 int main(){
157     scanf("%d",&t);
158     for(int z=1;z<=t;z++){
159         scanf("%d",&n);
160         memset(head,0,sizeof(head));
161         memset(son,0,sizeof(son));
162         memset(dep,0,sizeof(dep));
163         memset(fa,0,sizeof(fa));
164         memset(size,0,sizeof(size));
165         memset(ide,0,sizeof(ide));
166         memset(w,0,sizeof(w));
167         memset(ww,0,sizeof(ww));
168         memset(id,0,sizeof(id));
169         memset(top,0,sizeof(top));
170         tot=0;
171         cnt=0;
172         for(int i=1;i<=n-1;i++){
173             int u,v,w;
174             scanf("%d%d%d",&u,&v,&w);
175             add(u,v,w,i);
176             add(v,u,w,i);
177         }
178         dfs1(1,0,1);
179         dfs2(1,1);    
180         build(1,n,1);
181         while(scanf("%s",&s)!=EOF){
182             if(s[0]=='D')break;
183             if(s[0]=='Q'){
184                 int x,y;
185                 scanf("%d%d",&x,&y);
186                 int LCA=getlca(x,y);
187                 printf("%d\n",max(getmaxl(LCA,x),getmaxl(LCA,y)));
188             }
189             else if(s[0]=='C'){
190                 int x,y;
191                 scanf("%d%d",&x,&y);
192                 change(id[ide[x]],y,1);
193             }
194             else if(s[0]=='N'){
195                 int x,y;
196                 scanf("%d%d",&x,&y);
197                 int LCA=getlca(x,y);
198                 getfanl(LCA,x);
199                 getfanl(LCA,y);
200             }
201         }
202     }
203     return 0;
204 }

 

posted @ 2018-08-09 17:06  Xu-daxia  阅读(167)  评论(0编辑  收藏  举报