• P8973 『GROI-R1』 继续深潜,为了同一个梦想


    P8973 『GROI-R1』 继续深潜,为了同一个梦想

    P8973 『GROI-R1』 继续深潜,为了同一个梦想 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

    题目大意

    我称一棵树上的一个点集是“连接的”,当且仅当树上存在一条链能够覆盖这个点集并且这个集合大小不小于 2

    对于每个点,询问每个点被多少个这样的点集所包含

    a n s i ans_i ansi 为包含 i i i 号节点的连接的集合的个数对 1 0 9 + 7 10^9+7 109+7 取模后的值

    输出 x o r i = 1 n a n s i ∗ i xor_{i = 1}^n ans_i * i xori=1nansii

    思路

    换根 d p dp dp

    f r ( x ) f_r(x) fr(x) 为以 r r r 为根时,以 x x x 为一个端点,在 x x x 的子树里面选 ≥ 1 \ge1 1 个点,满足这些点在同一条链上面的方案数。

    那么:
    f r ( x ) = ∑ u ∈ s o n ( x ) f r ( u ) ∗ 2 + 1 f_r(x) = \sum_{u\in son(x)} f_r(u) * 2 + 1 fr(x)=uson(x)fr(u)2+1
    因为 u u u 点可以选也可以不选,并且可以选 { u , x } \{u , x\} {u,x}

    我算出所有 f f f 后考虑以 r r r 为根时的答案 a n s r ans_r ansr ,设 g r ( u ) = f r ( u ) ∗ 2 + 1 g_r(u) = f_r(u) * 2 + 1 gr(u)=fr(u)2+1

    其实就是 f r ( r ) f_r(r) fr(r) 加上两条链连起来的总和。

    那么:
    a n s r = ∑ u , v ∈ s o n ( r ) , u ≠ v g r ( u ) ∗ g r ( v ) + ∑ u ∈ s o n ( r ) g r ( u ) ans_r = \sum_{u , v \in son(r) , u \neq v} g_r(u) * g_r(v) + \sum _{u \in son(r)} g_r(u) ansr=u,vson(r),u=vgr(u)gr(v)+uson(r)gr(u)
    s r = ∑ u ∈ s o n ( r ) g r ( u ) s_r = \sum_{u \in son(r)} g_r(u) sr=uson(r)gr(u)

    那么:
    a n s r = ∑ u ∈ s o n ( r ) g r ( u ) ∗ ( s r − g r ( u ) + 1 ) ans_r = \sum_{u\in son(r)} g_r(u) * (s_r - g_r(u) + 1) ansr=uson(r)gr(u)(srgr(u)+1)
    实现的时候两条链组成一条新的链时不要多加了

    接下来考虑换根, u → v u\to v uv 换根,考虑 f f f 的变化
    f v ( u ) = f u ( u ) − ( f u ( v ) ∗ 2 + 1 ) f v ( v ) = f u ( v ) + f v ( u ) ∗ 2 + 1 f_v(u) =f_u(u) - (f_u(v) * 2 + 1) \newline f_v(v) = f_u(v) +f_v(u) * 2 +1 fv(u)=fu(u)(fu(v)2+1)fv(v)=fu(v)+fv(u)2+1
    其他的点 x x x 就是 f v ( x ) = f u ( x ) f_v(x) = f_u(x) fv(x)=fu(x)

    code

    #include 
    #define fu(x , y , z) for(int x = y ; x <= z ; x ++)
    #define LL long long
    using namespace std;
    const int N = 5e5 + 5;
    const LL mod = 1e9 + 7;
    int hd[N] , cnt , n , fa[N];
    LL f[N] , ans[N];
    struct E {
        int to , nt;
    } e[N << 1];
    void add (int x , int y) { e[++cnt].to = y , e[cnt].nt = hd[x] , hd[x] = cnt; }
    void dfs1 (int x) {
        int y;
        for (int i = hd[x] ; i ; i = e[i].nt) {
            y = e[i].to;
            if (y == fa[x]) continue;
            fa[y] = x;
            dfs1 (y);
            f[x] = (f[x] + f[y] * 2 % mod + 1) % mod;
        }
    }
    void dfs2 (int x) {
        int y;
        LL sum = 0;
        for (int i = hd[x] ; i ; i = e[i].nt) {
            y = e[i].to;
            sum = (sum + 2 * f[y] % mod + 1) % mod;
        }
        LL g;
        for (int i = hd[x] ; i ; i = e[i].nt) {
            y = e[i].to;
            g = (f[y] * 2 % mod + 1) % mod;
            ans[x] = (ans[x] + g * ((sum - g + mod + 1) % mod) % mod) % mod;
            sum = (sum - g + mod) % mod;
        }
        LL xx , yy;
        for (int i = hd[x] ; i ; i = e[i].nt) {
            y = e[i].to;
            if (y == fa[x]) continue;
            xx = f[x] , yy = f[y];
            f[x] = (xx + mod - (yy * 2 % mod + 1) % mod) % mod;
            f[y] = (yy + f[x] * 2 % mod + 1) % mod;
            dfs2 (y);
            f[x] = xx , f[y] = yy;
        }
    }
    int main () {
        int u , v;
        scanf ("%d" , &n);
        fu (i , 1 , n - 1) {
            scanf ("%d%d" , &u , &v);
            add (u , v) , add (v , u);
        }
        dfs1 (1);
        dfs2 (1);
        LL ans1 = ans[1] * 1;
        fu (i , 2 , n) ans1 = ans1 ^ (ans[i] * i);
        printf ("%lld" , ans1);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
  • 相关阅读:
    OAK相机通过振动测试!
    C++设计模式_09_Abstract Factory 抽象工厂
    后端研发工程师面经——Spring
    iOS描述文件(.mobileprovision)一键申请
    SquirrelMail实现Web方式收发邮件_xionglling的博客-CSDN博客
    链表中环的入口结点-算法题0002
    3D模型怎么贴法线贴图?
    从图文展示到以云为核,第五代验证码独有的策略情报能力
    idea中引入新JDK环境
    搜维尔科技:Geomagic Touch X力反馈设备【开箱图真机测试】
  • 原文地址:https://blog.csdn.net/fzyyyyyyyy/article/details/133844286