【线段树 树链剖分 差分 经典技巧】loj#3046. 「ZJOI2019」语言【未完】

吃可爱长大的小学妹 提交于 2020-01-15 21:36:41

还是来致敬一下那过往吧

 

题目分析

先丢代码

  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\n",(ans-det)/2);
128     return 0;
129 }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!