其他分享
首页 > 其他分享> > A层邀请赛4

A层邀请赛4

作者:互联网

A. 暗之链锁

翻书就好了,在树上差分的第一个例题,书上讲得太好了感觉我写啥都是多余。Cat本来可以1A的,结果把m看成了树边和非树边总共有m条,算贡献的时候算成了n-m...过样例的的时候读入错了我就发现了这个问题,结果改了一处没改第二处……

有大佬说能用树链剖分+线段树,我懒了就没试,我的树链剖分是用来找lca的。

#include <bits/stdc++.h>
  
using namespace std;
  
typedef long long ll;
const int maxn = 1e5 + 2;
const ll mod = 1e9 + 7;

int n, m, top[maxn], fa[maxn], siz[maxn], dfn[maxn], rnk[maxn];
int c[maxn], dep[maxn], son[maxn], ntime;
ll ans;

struct node 
{
    int next, to;
}a[maxn<<1];
int head[maxn], len;

void add(int x, int y)
{
    a[++len].to = y; a[len].next = head[x];
    head[x] = len;
}

void find_heavy_edge(int u, int fat, int depth)
{
    fa[u] = fat;
    dep[u] = depth;
    siz[u] = 1;
    son[u] = 0;
    int maxsize = 0;
    for(int i=head[u]; i; i=a[i].next)
    {
        int v = a[i].to;
        if(dep[v]) continue;
        find_heavy_edge(v, u, depth+1);
        siz[u] += siz[v];
        if(siz[v] > maxsize)
        {
            maxsize = siz[v];
            son[u] = v;
        }
    }
}

void connect_heavy_edge(int u, int ancestor)
{
    dfn[u] = ++ntime;
    top[u] = ancestor;
    rnk[ntime] = u;
    if(son[u])
    {
        connect_heavy_edge(son[u], ancestor);
    }
    for(int i=head[u]; i; i=a[i].next)
    {
        int v = a[i].to;
        if(v == son[u] || v == fa[u]) continue;
        connect_heavy_edge(v, v);
    }
}

int LCA(int x, int y)
{
    while(top[x] != top[y])
    {
        if(dep[top[x]] < dep[top[y]]) swap(x, y);
        x = fa[top[x]];
    }
    if(dep[x] > dep[y]) swap(x, y);
    return x;
}

void dfs(int u)
{
    for(int i=head[u]; i; i=a[i].next)
    {
        int v = a[i].to;
        if(v == fa[u]) continue;
        dfs(v);
        c[u] += c[v];
    }
    if(u != 1)
    {
        if(c[u] == 0) ans += m;
        else if(c[u] == 1) ans++;
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    for(int i=1; i<n; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y); add(y, x);
    }
    find_heavy_edge(1, 1, 1);
    connect_heavy_edge(1, 1);
    for(int i=1; i<=m; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        c[x]++; c[y]++;
        int lca = LCA(x, y);
        c[lca] -= 2;
    }
    dfs(1);
    printf("%lld\n", ans);
  
    return 0;
}
View Code

 

B. 蚊子

(如果你算错了,就会被liu_runda拿去喂兔子,啊呜~~)

我不会算,兔子你吃了我吧,撑不死你……

标签:fa,int,top,son,dep,maxn,邀请赛
来源: https://www.cnblogs.com/Catherine2006/p/16589803.html