zoukankan      html  css  js  c++  java
  • 【线段树 树链剖分 差分 经典技巧】loj#3046. 「ZJOI2019」语言【未完】

    还是来致敬一下那过往吧

    题目分析

    先丢代码

      1 #include<bits/stdc++.h>
      2 const int maxn = 100035;
      3 const int maxm = 200035;
      4 const int maxNode = 20000035;
      5 
      6 struct node
      7 {
      8     int top,son,fa,tot;
      9 }a[maxn];
     10 struct point
     11 {
     12     int u,v;
     13     point(int a=0, int b=0):u(a),v(b) {}
     14 };
     15 struct tree
     16 {
     17     int ls,rs,cov,val;
     18 }f[maxNode];
     19 int n,m,tot;
     20 long long ans,det;
     21 int chain[maxn],chTot,rt[maxn];
     22 int edgeTot,head[maxn],edges[maxm],nxt[maxm],dep[maxn];
     23 std::vector<point> opt[maxn];
     24 std::vector<int> inc[maxn],dec[maxn];
     25 
     26 int read()
     27 {
     28     char ch = getchar();
     29     int num = 0, fl = 1;
     30     for (; !isdigit(ch); ch=getchar())
     31         if (ch=='-') fl = -1;
     32     for (; isdigit(ch); ch=getchar())
     33         num = (num<<1)+(num<<3)+ch-48;
     34     return num*fl;
     35 }
     36 void addedge(int u, int v)
     37 {
     38     edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
     39     edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
     40 }
     41 void dfs1(int x, int fa)
     42 {
     43     dep[x] = dep[fa]+1, a[x].tot = 1;
     44     a[x].top = a[x].son = -1, a[x].fa = fa;
     45     for (int i=head[x]; i!=-1; i=nxt[i])
     46     {
     47         int v = edges[i];
     48         if (v==fa) continue;
     49         dfs1(v, x), a[x].tot += a[v].tot;
     50         if (a[x].son==-1||a[a[x].son].tot < a[v].tot)
     51             a[x].son = v;
     52     }
     53 }
     54 void dfs2(int x, int top)
     55 {
     56     a[x].top = top, chain[x] = ++chTot;
     57     if (a[x].son==-1) return;
     58     dfs2(a[x].son, top);
     59     for (int i=head[x]; i!=-1; i=nxt[i])
     60         if (edges[i]!=a[x].fa&&edges[i]!=a[x].son)
     61             dfs2(edges[i], edges[i]);
     62 }
     63 void splitChain(int id, int u, int v)
     64 {
     65     inc[u].push_back(id), inc[v].push_back(id);
     66     while (a[u].top!=a[v].top)
     67     {
     68         if (dep[a[u].top] > dep[a[v].top]) std::swap(u, v);
     69         opt[id].push_back(point(chain[a[v].top], chain[v]));
     70         v = a[a[v].top].fa;
     71     }
     72     if (dep[u] > dep[v]) std::swap(u, v);
     73     opt[id].push_back(point(chain[u], chain[v]));
     74     dec[u].push_back(id), dec[a[u].fa].push_back(id);
     75 }
     76 void pushup(int rt, int len)
     77 {
     78     if (f[rt].cov) f[rt].val = len;
     79     else f[rt].val = f[f[rt].ls].val+f[f[rt].rs].val;
     80 }
     81 void mergeSeg(int &u, int v, int l, int r)
     82 {
     83     if (!u||!v) u += v;
     84     else{
     85         int mid = (l+r)>>1;
     86         f[u].cov += f[v].cov;
     87         mergeSeg(f[u].ls, f[v].ls, l, mid);
     88         mergeSeg(f[u].rs, f[v].rs, mid+1, r);
     89     }
     90     pushup(u, r-l+1);
     91 }
     92 void update(int &rt, int L, int R, int l, int r, int c)
     93 {
     94     if (!rt) rt = ++tot;
     95     if (L <= l&&r <= R) f[rt].cov += c, pushup(rt, r-l+1);
     96     else{
     97         int mid = (l+r)>>1;
     98         if (L <= mid) update(f[rt].ls, L, R, l, mid, c);
     99         if (R > mid) update(f[rt].rs, L, R, mid+1, r, c);
    100     }
    101     pushup(rt, r-l+1);
    102 }
    103 void delta(int x, int fa)
    104 {
    105     for (int i=head[x]; i!=-1; i=nxt[i])
    106         if (edges[i]!=fa) delta(edges[i], x);
    107     for (int l=0; l<inc[x].size(); l++)
    108         for (int i=0,mx=opt[inc[x][l]].size(); i<mx; i++)
    109             update(rt[x], opt[inc[x][l]][i].u, opt[inc[x][l]][i].v, 1, n, 1);
    110     for (int l=0; l<dec[x].size(); l++)
    111         for (int i=0,mx=opt[dec[x][l]].size(); i<mx; i++)
    112             update(rt[x], opt[dec[x][l]][i].u, opt[dec[x][l]][i].v, 1, n, -1);
    113     int val = f[rt[x]].val;
    114     if (val) ans += val, ++det;
    115     mergeSeg(rt[fa], rt[x], 1, n);
    116 }
    117 int main()
    118 {
    119     memset(head, -1, sizeof head);
    120     n = read(), m = read();
    121     for (int i=1; i<n; i++)
    122         addedge(read(), read());
    123     dfs1(1, 0), dfs2(1, 1);
    124     for (int i=1; i<=m; i++)
    125         splitChain(i, read(), read());
    126     delta(1, 0);
    127     printf("%lld
    ",(ans-det)/2);
    128     return 0;
    129 }
  • 相关阅读:
    Linux rsync 命令详解
    docker 容器间网络配置
    git合并分支
    基于Docker的Mysql主从复制搭建
    MySQL字符串函数substring:字符串截取
    mysql 存储过程
    分布式系统唯一ID生成方案汇总 转
    mysql 比较函数和操作符
    Distributed PostgreSQL on a Google Spanner Architecture – Storage Layer
    Distributed PostgreSQL on a Google Spanner Architecture – Query Layer
  • 原文地址:https://www.cnblogs.com/antiquality/p/10846934.html
Copyright © 2011-2022 走看看