数链剖分(Tree)

Posted letlifestop

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数链剖分(Tree)相关的知识,希望对你有一定的参考价值。

题目链接:https://cn.vjudge.net/contest/279350#problem/D

题目大意:操作,单点查询,区间取反,询问区间最大值。

AC代码:

  1 #include<iostream>
  2 #include<cmath>
  3 #include<stack>
  4 #include<queue>
  5 #include<stdio.h>
  6 #include<string>
  7 #include<cstring>
  8 #include<algorithm>
  9 using namespace std;
 10 # define inf 0x3f3f3f3f
 11 # define ll long long
 12 # define lson l,m,rt<<1
 13 # define rson m+1,r,rt<<1|1
 14 const int maxn = 3e5+100;
 15 int sto[maxn],head[maxn],edgnum,dfsnum,depth[maxn];
 16 int son[maxn],father[maxn],Size[maxn],ord[maxn],cost[maxn],top[maxn];
 17 int maxtree[maxn<<2],mintree[maxn<<2],maxx,lazy[maxn<<2];
 18 struct node
 19 {
 20     int fr;
 21     int to;
 22     int nex;
 23     int cost;
 24 } edge[maxn],po[maxn];
 25 void addedge(int fr,int to)
 26 {
 27     edge[edgnum].fr=fr;
 28     edge[edgnum].to=to;
 29     edge[edgnum].nex=head[fr];
 30     head[fr]=edgnum++;
 31 }
 32 void dfs1(int fr,int rt,int dep)
 33 {
 34     father[fr]=rt;
 35     Size[fr]=1;
 36     son[fr]=-1;
 37     depth[fr]=dep;
 38     for(int i=head[fr]; i!=-1; i=edge[i].nex)
 39     {
 40         int to=edge[i].to;
 41         if(to==rt)
 42             continue;
 43         dfs1(to,fr,dep+1);
 44         Size[fr]+=Size[to];
 45         if(son[to]==-1||(Size[son[fr]]<Size[to]))
 46         {
 47             son[fr]=to;
 48         }
 49     }
 50 }
 51 void dfs2(int fr,int rt)
 52 {
 53     ord[fr]=++dfsnum;
 54     cost[ord[fr]]=sto[fr];
 55     top[fr]=rt;
 56     if(son[fr]!=-1)
 57         dfs2(son[fr],rt);
 58     for(int i=head[fr]; i!=-1; i=edge[i].nex)
 59     {
 60         int u=edge[i].to;
 61         if(son[fr]!=u&&father[fr]!=u)
 62         {
 63             dfs2(u,u);
 64         }
 65     }
 66 }
 67 void up(int rt)
 68 {
 69     maxtree[rt]=max(maxtree[rt<<1],maxtree[rt<<1|1]);
 70     mintree[rt]=min(mintree[rt<<1],mintree[rt<<1|1]);
 71 }
 72 void buildtree(int l,int r,int rt)
 73 {
 74     if(l==r)
 75     {
 76         maxtree[rt]=sto[l];
 77         mintree[rt]=sto[l];
 78         lazy[rt]++;
 79         return ;
 80     }
 81     int m=(l+r)>>1;
 82     buildtree(lson);
 83     buildtree(rson);
 84     up(rt);
 85 }
 86 void change(int rt)
 87 {
 88     int tmp=mintree[rt];
 89     mintree[rt]=-maxtree[rt];
 90     maxtree[rt]=-tmp;
 91 }
 92 void down(int rt)
 93 {
 94     if(!lazy[rt])
 95         return ;
 96     lazy[rt<<1]^=1;
 97     lazy[rt<<1|1]^=1;
 98     change(rt<<1);
 99     change(rt<<1|1);
100     lazy[rt]^=1;
101 }
102 void  query(int l,int r,int rt,int L,int R)
103 {
104     if(L<=l&&R>=r)
105     {
106         maxx=max(maxx,maxtree[rt]);
107         return ;
108     }
109     down(rt);
110     int m=(l+r)>>1;
111     if(L<=m)
112         query(lson,L,R);
113     if(R>m)
114         query(rson,L,R);
115     up(rt);
116 }
117 void update1(int l,int r,int rt,int pos,int p)
118 {
119     if(l==r)
120     {
121         maxtree[rt]=p;
122         mintree[rt]=p;
123         return ;
124     }
125     down(rt);
126     int m=(l+r)>>1;
127     if(pos<=m)
128         update1(lson,pos,p);
129     if(pos>m)
130         update1(rson,pos,p);
131     up(rt);
132 }
133 void update2(int l,int r,int rt,int L,int R)
134 {
135     if(L<=l&&R>=r)
136     {
137         change(rt);
138         lazy[rt]^=1;
139         return ;
140     }
141     down(rt);
142     int m=(l+r)>>1;
143     if(L<=m)
144         update2(lson,L,R);
145     if(R>m)
146         update2(rson,L,R);
147     up(rt);
148 }
149 void  Query(int n,int x,int y)
150 {
151     maxx=-inf;
152     int tx=top[x],ty=top[y];
153     while(tx!=ty)
154     {
155         if(depth[tx]<depth[ty])
156         {
157             swap(tx,ty);
158             swap(x,y);
159         }
160         query(1,n,1,ord[tx],ord[x]);
161         x=father[tx],tx=top[x];
162     }
163     if(depth[x]<depth[y])
164     {
165         swap(x,y);
166     }
167     query(1,n,1,ord[y]+1,ord[x]);
168 }
169 void Update(int n,int x,int  y)
170 {
171     int tx=top[x],ty=top[y];
172     while(tx!=ty)
173     {
174         if(depth[tx]<depth[ty])
175         {
176             swap(tx,ty);
177             swap(x,y);
178         }
179         update2(1,n,1,ord[tx],ord[x]);
180         x=father[tx],tx=top[x];
181     }
182     if(depth[x]<depth[y])
183     {
184         swap(x,y);
185     }
186     update2(1,n,1,ord[y]+1,ord[x]);
187 }
188 int main()
189 {
190     int T;
191     scanf("%d",&T);
192     while(T--)
193     {
194         dfsnum=edgnum=0;
195         int n,q,s;
196         scanf("%d",&n);
197         int t1,t2,t3;
198         memset(maxtree,0,sizeof(maxtree));
199         memset(mintree,0,sizeof(mintree));
200         memset(lazy,0,sizeof(lazy));
201         memset(head,-1,sizeof(head));
202         for(int i=1; i<=n-1; i++)
203         {
204             scanf("%d %d %d",&t1,&t2,&t3);
205             addedge(t1,t2);
206             addedge(t2,t1);
207             po[i].fr=t1;
208             po[i].to=t2;
209             po[i].cost=t3;
210         }
211         dfs1(1,-1,1);
212         dfs2(1,1);
213         for(int i=1; i<=n-1; i++)
214         {
215             t1=depth[po[i].fr];
216             t2=depth[po[i].to];
217             if(t1>t2)
218             {
219                 swap(po[i].fr,po[i].to);
220             }
221             update1(1,n,1,ord[po[i].to],po[i].cost);
222         }
223         char str[10];
224         while(~scanf("%s",str))
225         {
226             if(str[0]==D)
227                 break;
228             else  if(str[0]==Q)
229             {
230                 scanf("%d %d",&t1,&t2);
231                 Query(n,t1,t2);
232                 printf("%d
",maxx);
233             }
234             else if(str[0]==C)
235             {
236                 scanf("%d %d",&t1,&t2);
237                 update1(1,n,1,ord[po[t1].to],t2);
238             }
239             else if(str[0]==N)
240             {
241                 scanf("%d %d",&t1,&t2);
242                 Update(n,t1,t2);
243             }
244         }
245     }
246     return 0;
247 }

 

以上是关于数链剖分(Tree)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3237 Tree(树链剖分)

POJ 3723 Tree(树链剖分)

hdu 5044 Tree (树链剖分+标记数组)

SPOJ QTREE Query on a tree ——树链剖分 线段树

poj 3237 Tree(树链剖分,线段树)

POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)