树链剖分模板题+模板

FJUTOJ2790

这个题贼麻烦 要线段树这么多功能   这颗线段树现在已经同时具备了区间加区间开根区间赋值区间求和区间最大区间最小

  1 #include<stdio.h>
  2 #include<math.h>
  3 #include<string.h>
  4 #include<algorithm>
  5 using namespace std;
  6 const int N=1e4+7;
  7 
  8 int n;
  9 
 10 int id[N],prid[N],deep[N],fa[N],Size[N],son[N],top[N],tot;
 11 
 12 inline char getcharc()
 13 {
 14     static const int BUFSIZE=100001;
 15     static char buf[BUFSIZE],*psta=buf,*pend=buf;
 16     if(psta==pend)
 17     {
 18         psta=buf;
 19         pend=buf+fread(buf,1,BUFSIZE,stdin);
 20         if(psta==pend)
 21             return -1;
 22     }
 23     return *psta++;
 24 }
 25 
 26 float SqrtByCarmack( float number )
 27 {
 28     int i;
 29     float x2, y;
 30     const float threehalfs = 1.5F;
 31 
 32     x2 = number * 0.5F;
 33     y  = number;
 34     i  = * ( int * ) &y;
 35     i  = 0x5f375a86 - ( i >> 1 );
 36     y  = * ( float * ) &i;
 37     y  = y * ( threehalfs - ( x2 * y * y ) );
 38     y  = y * ( threehalfs - ( x2 * y * y ) );
 39     y  = y * ( threehalfs - ( x2 * y * y ) );
 40     return number*y;
 41 }
 42 inline void nextInt(int &x) {//读取一个整型
 43 
 44     char c;
 45     do c=getcharc(); while (c<'0'||c>'9');
 46     x=c-'0';
 47     while ('0'<=(c=getcharc())&&c<='9') x=x*10+c-'0';
 48 }
 49 inline void nextInt(long long &x) {//读取一个整型
 50 
 51     char c;
 52     do c=getcharc(); while (c<'0'||c>'9');
 53     x=c-'0';
 54     while ('0'<=(c=getcharc())&&c<='9') x=x*10+c-'0';
 55 }
 56 struct Segment_tree
 57 {
 58     struct Node
 59     {
 60         long long val,Max,lazy,Min,lazyf;
 61         int Size,son[2];
 62         void init()
 63         {
 64             lazy=son[0]=son[1]=Size=val=Max=val=lazyf=0;
 65         }
 66     } T[N*4];
 67     int cnt,root;
 68 
 69     void init(int l,int r,long long *a)
 70     {
 71         cnt=0;
 72         root=build(l,r,a);
 73     }
 74 
 75     inline void update(int pos)
 76     {
 77         if(T[pos].Size==1)return ;
 78         T[pos].val=T[T[pos].son[0]].val+T[T[pos].son[1]].val;
 79         T[pos].Max=max(T[T[pos].son[0]].Max,T[T[pos].son[1]].Max);
 80         T[pos].Min=min(T[T[pos].son[0]].Min,T[T[pos].son[1]].Min);
 81     }
 82 
 83     inline void pushdown(int pos)
 84     {
 85         int lc=T[pos].son[0],rc=T[pos].son[1];
 86         if(T[pos].lazyf)
 87         {
 88             if(lc)
 89             {
 90                 T[lc].lazyf=T[pos].lazyf;
 91                 T[lc].val=T[pos].lazyf*T[lc].Size;
 92                 T[lc].Max=T[lc].Min=T[pos].lazyf;
 93                 T[lc].lazy=0;
 94             }
 95             if(rc)
 96             {
 97                 T[rc].lazyf=T[pos].lazyf;
 98                 T[rc].val=T[pos].lazyf*T[rc].Size;
 99                 T[rc].Max=T[rc].Min=T[pos].lazyf;
100                 T[rc].lazy=0;
101             }
102             T[pos].lazyf=0;
103         }
104         if(T[pos].lazy)
105         {
106             if(lc)
107             {
108                 T[lc].lazy+=T[pos].lazy;
109                 T[lc].val+=T[pos].lazy*T[lc].Size;
110                 T[lc].Max+=T[pos].lazy;
111                 T[lc].Min+=T[pos].lazy;
112             }
113             if(rc)
114             {
115                 T[rc].lazy+=T[pos].lazy;
116                 T[rc].val+=T[pos].lazy*T[rc].Size;
117                 T[rc].Max+=T[pos].lazy;
118                 T[rc].Min+=T[pos].lazy;
119             }
120             T[pos].lazy=0;
121         }
122     }
123 
124     inline int build(int l,int r,long long *a)
125     {
126         long long pos=++cnt;
127         T[pos].init();
128         T[pos].Size=r-l+1;
129         if(l==r)
130         {
131             T[pos].val=a[l];
132             T[pos].Max=a[l];
133             T[pos].Min=a[l];
134             return pos;
135         }
136         int mid=(l+r)>>1;
137         T[pos].son[0]=build(l,mid,a);
138         T[pos].son[1]=build(mid+1,r,a);
139         update(pos);
140         return pos;
141     }
142 
143     void add(int L,int R,int l,int r,long long v,int pos=1)
144     {
145         if(L==l&&R==r)
146         {
147             T[pos].val+=v*(r-l+1);
148             T[pos].lazy+=v;
149             T[pos].Max+=v;
150             T[pos].Min+=v;
151             return ;
152         }
153         pushdown(pos);
154         int mid=(L+R)>>1;
155         if(r<=mid)
156             add(L,mid,l,r,v,T[pos].son[0]);
157         else if(l>mid)
158             add(mid+1,R,l,r,v,T[pos].son[1]);
159         else
160         {
161             add(L,mid,l,mid,v,T[pos].son[0]);
162             add(mid+1,R,mid+1,r,v,T[pos].son[1]);
163         }
164         update(pos);
165     }
166 
167     void cover(int L,int R,int l,int r,long long v,int pos=1)
168     {
169         if(L==l&&R==r)
170         {
171             T[pos].lazyf=v;
172             T[pos].val=T[pos].lazyf*T[pos].Size;
173             T[pos].Max=T[pos].lazyf;
174             T[pos].Min=T[pos].lazyf;
175             T[pos].lazy=0;
176             return ;
177         }
178         pushdown(pos);
179         int mid=(L+R)>>1;
180         if(r<=mid)
181             cover(L,mid,l,r,v,T[pos].son[0]);
182         else if(l>mid)
183             cover(mid+1,R,l,r,v,T[pos].son[1]);
184         else
185         {
186             cover(L,mid,l,mid,v,T[pos].son[0]);
187             cover(mid+1,R,mid+1,r,v,T[pos].son[1]);
188         }
189         update(pos);
190     }
191 
192     void qrt(int L,int R,int l,int r,int pos=1)
193     {
194         if(r==R&&l==L&&(int)(SqrtByCarmack(T[pos].Max)+0.0001)==(int)(SqrtByCarmack(T[pos].Min)+0.0001))
195         {
196             cover(L,R,l,r,SqrtByCarmack(T[pos].Max)+0.0001,pos);
197             return ;
198         }
199         if(r==R&&l==L&&T[pos].Max-T[pos].Min<=1)
200         {
201             add(L,R,l,r,(int)(SqrtByCarmack(T[pos].Max)+0.0001)-T[pos].Max,pos);
202             return ;
203         }
204         pushdown(pos);
205         int mid=(L+R)>>1;
206         if(r==R&&l==L)
207         {
208             qrt(L,mid,l,mid,T[pos].son[0]);
209             qrt(mid+1,R,mid+1,r,T[pos].son[1]);
210         }
211         else if(r<=mid)
212             qrt(L,mid,l,r,T[pos].son[0]);
213         else if(l>mid)
214             qrt(mid+1,R,l,r,T[pos].son[1]);
215         else
216         {
217             qrt(L,mid,l,mid,T[pos].son[0]);
218             qrt(mid+1,R,mid+1,r,T[pos].son[1]);
219         }
220         update(pos);
221     }
222 
223     long long query_Sum(int L,int R,int l,int r,int pos=1)
224     {
225         if(L==l&&R==r)
226         {
227             return T[pos].val;
228         }
229         pushdown(pos);
230         int mid=(L+R)>>1;
231         if(r<=mid)
232             return query_Sum(L,mid,l,r,T[pos].son[0]);
233         else if(l>mid)
234             return query_Sum(mid+1,R,l,r,T[pos].son[1]);
235         else
236             return query_Sum(L,mid,l,mid,T[pos].son[0])+query_Sum(mid+1,R,mid+1,r,T[pos].son[1]);
237     }
238 }tree;
239 int first[N],sign;
240 struct node
241 {
242     int to,next;
243 }edge[N*4];
244 void creat()
245 {
246     memset(first,0,sizeof(first));
247     sign=1;
248 }
249 void add_edge(int from,int to)
250 {
251     edge[sign].to=to;
252     edge[sign].next=first[from];
253     first[from]=sign++;
254 }
255 
256 void dfs1(int now,int pre,int d)
257 {
258     deep[now]=d,fa[now]=pre,Size[now]=1;
259     for(int i=first[now];i;i=edge[i].next)
260     {
261         int to=edge[i].to;;
262         if(to==pre)continue;
263         dfs1(to,now,d+1);
264         Size[now]+=Size[to];
265         if(!son[now]||Size[to]>Size[son[now]])
266             son[now]=to;
267     }
268 }
269 void dfs2(int now,int Top)
270 {
271     top[now]=Top,id[now]=++tot;
272     prid[id[now]]=now;
273     if(!son[now])return ;
274     dfs2(son[now],Top);
275     for(int i=first[now];i;i=edge[i].next)
276     {
277         int to=edge[i].to;
278         if(to!=son[now]&&to!=fa[now])
279         {
280             dfs2(to,to);
281         }
282 
283     }
284 }
285 
286 long long tree_query(int x,int y)
287 {
288     int f1=top[x],f2=top[y];
289     long long ans=0;
290     while(f1!=f2)
291     {
292         if(deep[f1]<deep[f2])swap(f1,f2),swap(x,y);
293 
294         ans+=tree.query_Sum(1,n,id[f1],id[x]);
295         x=fa[f1],f1=top[x];
296     }
297     ans+=(deep[x]>deep[y])?tree.query_Sum(1,n,id[y],id[x]):tree.query_Sum(1,n,id[x],id[y]);
298     return ans;
299 }
300 
301 void tree_add(int x,int y,long long v)
302 {
303     int f1=top[x],f2=top[y];
304     while(f1!=f2)
305     {
306         if(deep[f1]<deep[f2])swap(f1,f2),swap(x,y);
307         tree.add(1,n,id[f1],id[x],v);
308         x=fa[f1],f1=top[x];
309     }
310     deep[x]>deep[y]?tree.add(1,n,id[y],id[x],v):tree.add(1,n,id[x],id[y],v);
311 }
312 
313 void tree_sqrt(int x,int y)
314 {
315     int f1=top[x],f2=top[y];
316     while(f1!=f2)
317     {
318         if(deep[f1]<deep[f2])swap(f1,f2),swap(x,y);
319         tree.qrt(1,n,id[f1],id[x]);
320         x=fa[f1],f1=top[x];
321     }
322     deep[x]>deep[y]?tree.qrt(1,n,id[y],id[x]):tree.qrt(1,n,id[x],id[y]);
323 }
324 
325 long long a[N];
326 
327 int main()
328 {
329     //freopen("test.txt","r",stdin);
330     //freopen("output1.txt","w",stdout);
331     int q;
332     nextInt(n),nextInt(q);
333     creat();
334     int x,y;
335     for(int i=1;i<n;i++)
336     {
337         nextInt(x),nextInt(y);
338         add_edge(x,y);
339         add_edge(y,x);
340     }
341     dfs1(1,0,1);
342     dfs2(1,1);
343     for(int i=1;i<=n;i++)
344         nextInt(a[id[i]]);
345     tree.init(1,n,a);
346     long long op,v;
347     while(q--)
348     {
349         nextInt(op);
350         if(op==1)
351         {
352             nextInt(x);
353             nextInt(y);
354             nextInt(v);
355             tree_add(x,y,v);
356         }
357         else if(op==2)
358         {
359             nextInt(x);
360             nextInt(y);
361             tree_sqrt(x,y);
362         }
363         else
364         {
365             nextInt(x);
366             nextInt(y);
367             printf("%lld
",tree_query(x,y));
368         }
369     }
370     return 0;
371 }
原文地址:https://www.cnblogs.com/xseventh/p/7344408.html