zoukankan      html  css  js  c++  java
  • 树链剖分

    study from:

    http://www.cnblogs.com/chinhhh/p/7965433.html

    https://www.luogu.org/problemnew/show/P3384

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <time.h>
      6 #include <string>
      7 #include <set>
      8 #include <map>
      9 #include <list>
     10 #include <stack>
     11 #include <queue>
     12 #include <vector>
     13 #include <bitset>
     14 #include <ext/rope>
     15 #include <algorithm>
     16 #include <iostream>
     17 using namespace std;
     18 #define ll long long
     19 #define minv 1e-6
     20 #define inf 1e9
     21 #define pi 3.1415926536
     22 #define nl 2.7182818284
     23 //const ll mod=1e9+7;//998244353
     24 const int maxn=1e5+10;
     25 
     26 struct node
     27 {
     28     int d;
     29     node *next;
     30 }*e[maxn];
     31 
     32 ll mod,tag[maxn<<2],sum[maxn<<2];
     33 int dep[maxn],siz[maxn],fa[maxn]={0},son[maxn],id[maxn],top[maxn],num=0,n;
     34 bool vis[maxn]={0};
     35 ll v[maxn],point_num=0,old_id[maxn];
     36 
     37 void dfs1(int d,int deep)
     38 {
     39     node *p=e[d];
     40     int maxson=0,dd;
     41     vis[d]=1;
     42     dep[d]=deep;
     43     siz[d]=1;
     44     while (p)
     45     {
     46         dd=p->d;
     47         if (!vis[dd])
     48         {
     49             fa[dd]=d;
     50             dfs1(dd,deep+1);
     51             siz[d]+=siz[dd];
     52             if (siz[dd]>maxson)
     53                 son[d]=dd,maxson=siz[dd];
     54         }
     55         p=p->next;
     56     }
     57 }
     58 
     59 void dfs2(int d,int topd)
     60 {
     61     id[d]=++num;
     62     top[d]=topd;
     63     old_id[num]=d;
     64     if (son[d]!=0)
     65     {
     66         dfs2(son[d],topd);
     67         node *p=e[d];
     68         int dd;
     69         while (p)
     70         {
     71             dd=p->d;
     72             if (dd!=fa[d] && dd!=son[d])
     73                 dfs2(dd,dd);
     74             p=p->next;
     75         }
     76     }
     77 }
     78 
     79 void build(int index,int l,int r)
     80 {
     81     tag[index]=0;
     82     if (l==r)
     83     {
     84 //        scanf("%lld",&sum[index]);
     85         sum[index]=v[old_id[++point_num]];
     86 //        sum[index]=sum[index]%mod;
     87     }
     88     else
     89     {
     90         int m=(l+r)>>1;
     91         build(index<<1,l,m);
     92         build(index<<1|1,m+1,r);
     93         sum[index]=(sum[index<<1]+sum[index<<1|1])%mod;
     94     }
     95 }
     96 
     97 void push_down(int index,int len)
     98 {
     99     tag[index<<1]=(tag[index]+tag[index<<1])%mod;
    100     tag[index<<1|1]=(tag[index]+tag[index<<1|1])%mod;
    101     sum[index<<1]=(tag[index]*((len+1)>>1)+sum[index<<1])%mod;
    102     sum[index<<1|1]=(tag[index]*(len>>1)+sum[index<<1|1])%mod;
    103     tag[index]=0;
    104 }
    105 
    106 void update(int index,int l,int r,int x,int y,ll k)
    107 {
    108     if (x<=l && r<=y)
    109     {
    110         sum[index]=(k*(r-l+1)+sum[index])%mod;
    111         tag[index]=(k+tag[index])%mod;
    112         return;
    113     }
    114     if (tag[index]!=0)
    115         push_down(index,r-l+1);
    116     int m=(l+r)>>1;
    117     if (x<=m)
    118         update(index<<1,l,m,x,y,k);
    119     if (m<y)
    120         update(index<<1|1,m+1,r,x,y,k);
    121     sum[index]=(sum[index<<1]+sum[index<<1|1])%mod;
    122 }
    123 
    124 ll query(int index,int l,int r,int x,int y)
    125 {
    126     if (x<=l && r<=y)
    127         return sum[index];
    128     if (r<x || l>y)
    129         return 0;
    130     if (tag[index]!=0)
    131         push_down(index,r-l+1);
    132     int m=(l+r)>>1;
    133     return (query(index<<1,l,m,x,y)+query(index<<1|1,m+1,r,x,y))%mod;
    134 }
    135 
    136 void work1(int x,int y,ll k)
    137 {
    138     while (top[x]!=top[y])
    139     {
    140         if (dep[top[x]]<dep[top[y]])
    141             swap(x,y);
    142         update(1,1,n,id[top[x]],id[x],k);
    143         x=fa[top[x]];
    144     }
    145     if (dep[x]<dep[y])
    146         swap(x,y);
    147     update(1,1,n,id[y],id[x],k);
    148 }
    149 
    150 ll work2(int x,int y)
    151 {
    152     ll tot=0;
    153     while (top[x]!=top[y])
    154     {
    155         if (dep[top[x]]<dep[top[y]])    ///top!
    156             swap(x,y);
    157         tot=(tot+query(1,1,n,id[top[x]],id[x]))%mod;
    158         x=fa[top[x]];
    159     }
    160     if (dep[x]<dep[y])
    161         swap(x,y);
    162     tot=(tot+query(1,1,n,id[y],id[x]))%mod;
    163     return tot;
    164 }
    165 
    166 void work3(int x,ll k)
    167 {
    168     update(1,1,n,id[x],id[x]+siz[x]-1,k);
    169 }
    170 
    171 ll work4(int x)
    172 {
    173     return query(1,1,n,id[x],id[x]+siz[x]-1);
    174 }
    175 
    176 int main()
    177 {
    178     node *p;
    179     int q,root,x,y,mode,i;
    180     ll k;
    181     scanf("%d%d%d%lld",&n,&q,&root,&mod);
    182     for (i=1;i<=n;i++)
    183         scanf("%lld",&v[i]);
    184     for (i=1;i<n;i++)
    185     {
    186         scanf("%d%d",&x,&y);
    187         p=(node*) malloc (sizeof(node));
    188         p->d=y;
    189         p->next=e[x];
    190         e[x]=p;
    191 
    192         p=(node*) malloc (sizeof(node));
    193         p->d=x;
    194         p->next=e[y];
    195         e[y]=p;
    196     }
    197 
    198     dfs1(root,0);
    199     dfs2(root,root);    ///two root
    200     build(1,1,n);
    201 
    202     while (q--)
    203     {
    204         scanf("%d",&mode);
    205         if (mode==1)
    206         {
    207             scanf("%d%d%lld",&x,&y,&k);
    208             work1(x,y,k);
    209         }
    210         else if (mode==2)
    211         {
    212             scanf("%d%d",&x,&y);
    213             printf("%lld
    ",work2(x,y));
    214         }
    215         else if (mode==3)
    216         {
    217             scanf("%d%lld",&x,&k);
    218             work3(x,k);
    219         }
    220         else
    221         {
    222             scanf("%d",&x);
    223             printf("%lld
    ",work4(x));
    224         }
    225     }
    226     return 0;
    227 }
    228 /*
    229 5 100 2 10000000
    230 0 0 0 0 0
    231 1 2
    232 1 5
    233 3 1
    234 4 1
    235 1 5 4 1
    236 1 2 5 1
    237 2 4 5
    238 */
  • 相关阅读:
    深入理解 JavaScript(五)
    深入理解 JavaScript(四)
    深入理解 JavaScript(三)
    opecv官网接口查询
    一个python-opencv博客
    Python中range和xrange的区别
    【转载】opencv 二值化函数——cv2.threshold
    python-opencv中的cv2.inRange函数
    anaconda conda install wxpython4 安装包 python3环境(GUI)
    python之assert
  • 原文地址:https://www.cnblogs.com/cmyg/p/9568334.html
Copyright © 2011-2022 走看看