zoukankan      html  css  js  c++  java
  • AC230祭!!(树链剖分)(180921更新)

    今天闲的搜了一下.cpp...

    神奇的Windows告诉我有499个文件;

    吓得我赶紧写了一道水题...就500

    虽然不多但是开心(^_^)

    (附上树链表示庆祝)

    树链剖分求LCA

    复杂度忘了但是是本菜鸡已知的唯一能过luoguP3379的 = =

    首先普及一下链(重链)

    重链就是每次都从下两个儿子中选择较大的一个接上...

    往下子孙的个数多的叫大儿子(回溯...)

    根是第一个起点,找完一条链就从剩下的中选择深度dep最小的继续

    然鹅有什么用??

    求解过程:

    ①输入x,y

    ②求出链顶(起点)

    ③判断是否相同

    如果相同:

    LCA就是深度较小的那个(不解释),break

    如果不同:

    选择深度较深的往上走一步(省时啊!!)

    ⑤继续判断

    ⑨结束

    ②③覆盖x,y值

    代码贴上(read()快读可以用标输)


    18.09.21 更新

    很久以前的blog……感慨颇多啊

    前两天在网上到处搜最后还是看了自己的博客重新学会的……

    粘一下代码lo

    luoguP3384

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #define rep(i,a,n) for(int i = a;i <= n;i++)
      7 #define per(i,n,a) for(int i = n;i >= a;i--)
      8 #define ls t<<1
      9 #define rs t<<1|1
     10 using namespace std;
     11 typedef long long ll;
     12 int read() {
     13     int as = 0,fu = 1;
     14     char c = getchar();
     15     while(c < '0' || c > '9') {
     16         if(c == '-') fu = -1;
     17         c = getchar();
     18     }
     19     while(c >= '0' && c <= '9') {
     20         as = as * 10 + c - '0';
     21         c = getchar();
     22     }
     23     return as * fu;
     24 }
     25 
     26 const int N = 200005;
     27 //head
     28 
     29 int n,T,s,mod;
     30 int cnt,cur,head[N],nxt[N],mo[N];
     31 int w[N],a[N],p[N<<2],add[N<<2];
     32 int id[N],pa[N],mson[N],top[N],sz[N],dep[N];
     33 
     34 void addline(int x,int y) {
     35     mo[++cnt] = y;
     36     nxt[cnt] = head[x];
     37     head[x] = cnt;
     38     mo[++cnt] = x;
     39     nxt[cnt] = head[y];
     40     head[y] = cnt;
     41     return;
     42 }
     43 
     44 void dfs1(int x,int fa,int d) {
     45     dep[x] = d;
     46     pa[x] = fa;
     47     sz[x] = 1;
     48     int maxson = -1;
     49     for(int i = head[x]; i; i = nxt[i]) {
     50         int sn = mo[i];
     51         if(sn == fa) continue;
     52         dfs1(sn,x,d+1);
     53         sz[x] += sz[sn];
     54         if(sz[sn] > maxson) {
     55             mson[x] = sn;
     56             maxson = sz[sn];
     57         }
     58     }
     59 }
     60 void dfs2(int x,int topx) {
     61     id[x] = ++cur;
     62     a[cur] = w[x];
     63     top[x] = topx;
     64     if(mson[x] == 0) return;
     65     dfs2(mson[x],topx);
     66     for(int i = head[x]; i; i = nxt[i]) {
     67         int sn = mo[i];
     68         if(sn == mson[x] || sn == pa[x]) continue;
     69         dfs2(sn,sn);
     70     }
     71     return;
     72 }
     73 
     74 inline void pup(int t) {
     75     p[t] = (p[ls] + p[rs]) % mod;
     76 }
     77 inline void pdown(int l,int r,int t) {
     78     if(add[t] == 0) return;
     79     int m = l+r >> 1;
     80     int szl = m+1-l;
     81     int szr = r-m;
     82     p[ls] = (p[ls] + add[t] * szl) % mod;
     83     p[rs] = (p[rs] + add[t] * szr) % mod;
     84     add[ls] = (add[ls] + add[t]) % mod;
     85     add[rs] = (add[rs] + add[t]) % mod;
     86     add[t] = 0;
     87     return;
     88 }
     89 void build(int l,int r,int t) {
     90     if(l == r) {
     91         p[t] = a[l];
     92         return;
     93     }
     94     int m = l+r >>1;
     95     build(l,m,ls);
     96     build(m+1,r,rs);
     97     pup(t);
     98     return;
     99 }
    100 void Segupdate(int L,int R,int c,int l,int r,int t) {
    101     if(L <= l && r <= R) {
    102         p[t] = (p[t] + c * (r - l + 1)) % mod;
    103         add[t] = (add[t] + c) % mod;
    104         return;
    105     }
    106     pdown(l,r,t);
    107     int m = l+r >> 1;
    108     if(L <= m) Segupdate(L,R,c,l,m,ls);
    109     if(R >  m) Segupdate(L,R,c,m+1,r,rs);
    110     pup(t);
    111     return;
    112 }
    113 int Segquery(int L,int R,int l,int r,int t) {
    114     if(L <= l && r <= R) return p[t];
    115     pdown(l,r,t);
    116     int m = l+r >> 1;
    117     int ans = 0;
    118     if(L <= m) ans = (ans + Segquery(L,R,l,m,ls)) % mod;
    119     if(R >  m) ans = (ans + Segquery(L,R,m+1,r,rs)) % mod;
    120     return ans;
    121 }
    122 
    123 void Lineupdate(int x,int y,int z) {
    124     while(top[x] != top[y]) {
    125         if(dep[top[x]] < dep[top[y]]) swap(x,y);
    126         Segupdate(id[top[x]],id[x],z,1,n,1);
    127         x = pa[top[x]];
    128     }
    129     if(dep[x] < dep[y]) swap(x,y);
    130     Segupdate(id[y],id[x],z,1,n,1);
    131     return;
    132 }
    133 int Linequery(int x,int y) {
    134     int ans = 0;
    135     while(top[x] != top[y]) {
    136         if(dep[top[x]] < dep[top[y]]) swap(x,y);
    137         ans = (ans + Segquery(id[top[x]],id[x],1,n,1)) % mod;
    138         x = pa[top[x]];
    139     }
    140     if(dep[x] < dep[y]) swap(x,y);
    141     ans = (ans + Segquery(id[y],id[x],1,n,1)) % mod;
    142     return ans;
    143 }
    144 
    145 void Sonupdate(int x,int z) {
    146     Segupdate(id[x],id[x] + sz[x] - 1,z,1,n,1);
    147     return;
    148 }
    149 int Sonquery(int x) {
    150     return Segquery(id[x],id[x] + sz[x] - 1,1,n,1);
    151 }
    152 int main() {
    153     n = read(),T = read(),s = read(),mod = read();
    154     rep(i,1,n) w[i] = read() % mod;
    155     rep(i,2,n) addline(read(),read());
    156     dfs1(s,0,0);
    157     dfs2(s,s);
    158     build(1,n,1);
    159     while(T--) {
    160         int op = read();
    161         if(op == 1) {
    162             int x = read();
    163             int y = read();
    164             int z = read() % mod;
    165             Lineupdate(x,y,z);
    166         }
    167         if(op == 2) {
    168             int x = read();
    169             int y = read();
    170             printf("%d
    ",Linequery(x,y));
    171         }
    172         if(op == 3) {
    173             int x = read();
    174             int z = read() % mod;
    175             Sonupdate(x,z);
    176 
    177         }
    178         if(op == 4) {
    179             int x = read();
    180             printf("%d
    ",Sonquery(x));
    181         }
    182     }
    183     return 0;
    184 }

    有点小小的忧伤啊……

    > 别忘了 总有人在等着你
  • 相关阅读:
    类中以双下划线開始的方法
    Dynamics CRM2016 新功能之从CRM APP中导出数据至EXCEL
    敏捷项目管理实践
    Hibernate环境搭建
    ubuntu12.04更新软件源时出现校验和不符
    修炼你自己
    http自己定义超时检測方法、主动抛出异常
    sql server 2008安装图解
    Ural 1353 Milliard Vasya&#39;s Function(DP)
    待字闺中之构造最大数分析
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/8460191.html
Copyright © 2011-2022 走看看