• 树链剖分模板题+模板


    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 }
  • 相关阅读:
    IO之同步、异步、阻塞、非阻塞 (2)
    IO之同步、异步、阻塞、非阻塞
    Syncthing源码解析
    Syncthing源码解析
    在Gogland里对GO程序进行单元测试!
    GO学习笔记
    GO学习笔记
    GO学习笔记
    GO学习笔记
    GO学习笔记
  • 原文地址:https://www.cnblogs.com/xseventh/p/7344408.html
Copyright © 2020-2023  润新知