# 电路(权限题)

  1 #include <bits/stdc++.h>
2
3 typedef long long LL;
4
5 const int N = 600010, MO = 998244353;
6
7 struct Edge {
8     int nex, v, len;
9 }edge[N << 1]; int tp;
10
11 int n, e[N], a[N], ans, rt[N], m;
12
13 namespace seg {
14     const int V = 15000000;
15     int ls[V], rs[V], sum[2][2][V], siz[V], sl[2][2], sr[2][2], tot;
16     inline void pushup(int l, int r, int o) {
17         int mid = (l + r) >> 1, L = ls[o], R = rs[o], len = mid - l + 1, len2 = r - mid;
18         int f = (mid - l + 1) & 1, f2 = siz[L] & 1;
19
20         siz[o] = siz[L] + siz[R];
21
22         if(L) {
23             sl[0][0] = sum[0][0][L];
24             sl[0][1] = sum[0][1][L];
25             sl[1][0] = sum[1][0][L];
26             sl[1][1] = sum[1][1][L];
27         }
28         else {
29             sl[0][0] = len >> 1;
30             sl[0][1] = 0;
31             sl[1][0] = (len + 1) >> 1;
32             sl[1][1] = 0;
33         }
34
35         if(R) {
36             sr[0][0] = sum[0][0][R];
37             sr[0][1] = sum[0][1][R];
38             sr[1][0] = sum[1][0][R];
39             sr[1][1] = sum[1][1][R];
40         }
41         else {
42             sr[0][0] = len2 >> 1;
43             sr[0][1] = 0;
44             sr[1][0] = (len2 + 1) >> 1;
45             sr[1][1] = 0;
46         }
47
48         sum[0][0][o] = sl[0][0] + sr[f][f2];
49         sum[0][1][o] = sl[0][1] + sr[f][f2 ^ 1];
50         sum[1][0][o] = sl[1][0] + sr[f ^ 1][f2];
51         sum[1][1][o] = sl[1][1] + sr[f ^ 1][f2 ^ 1];
52         return;
53     }
54     void insert(int p, int l, int r, int &o) {
55         if(!o) {
56             o = ++tot;
57         }
58         if(l == r) {
59             siz[o] = sum[1][1][o] = 1;
60             return;
61         }
62         int mid = (l + r) >> 1;
63         if(p <= mid) {
64             insert(p, l, mid, ls[o]);
65         }
66         else {
67             insert(p, mid + 1, r, rs[o]);
68         }
69         pushup(l, r, o);
70         return;
71     }
72     int merge(int x, int y, int l, int r) {
73         if(!x || !y) {
74             return x | y;
75         }
76         int mid = (l + r) >> 1;
77         ls[x] = merge(ls[x], ls[y], l, mid);
78         rs[x] = merge(rs[x], rs[y], mid + 1, r);
79         pushup(l, r, x);
80         return x;
81     }
82
83     inline void calc(int x, int v) {
84         int temp = (LL)(sum[0][0][x] + 1) * sum[0][1][x] % MO;
85         //printf("temp = %d \n", temp);
86         temp = (temp + (LL)sum[1][0][x] * sum[1][1][x] % MO) % MO;
87         //printf("temp += %d * %d\n", sum[1][0][x], sum[1][1][x]);
88         ans = (ans + (LL)temp * v % MO) % MO;
89         //printf("ans += %d * %d \n", temp, v);
90         return;
91     }
92 }
93
94 inline void add(int x, int y, int z) {
95     edge[++tp].v = y;
96     edge[tp].len = z;
97     edge[tp].nex = e[x];
98     e[x] = tp;
99     return;
100 }
101
102 void DFS(int x, int fa, int v) {
103     for(int i = e[x]; i; i = edge[i].nex) {
104         int y = edge[i].v;
105         if(y == fa) {
106             continue;
107         }
108         DFS(y, x, edge[i].len);
109         rt[x] = seg::merge(rt[x], rt[y], 1, m);
110     }
111     //printf("x = %d \n", x);
112     seg::calc(rt[x], v);
113     return;
114 }
115
116 int main() {
117
118     freopen("electricity.in", "r", stdin);
119     freopen("electricity.out", "w", stdout);
120
121     scanf("%d%d", &n, &m);
122     int x, y;
123     LL z;
124     for(int i = 1; i < n; i++) {
125         scanf("%d%d%lld", &x, &y, &z);
128     }
129     for(int i = 1; i <= m; i++) {
130         scanf("%d", &a[i]);
131         seg::insert(i, 1, m, rt[a[i]]);
132     }
133
134     DFS(1, 0, 0);
135
136     printf("%d\n", ans);
137     return 0;
138 }
139 /*
140 4 4
141 1 2 1
142 2 3 2
143 3 4 1
144 2 3 1 4
145 ------------------------
146 11
147 */
AC代码

posted @ 2019-06-28 09:42 huyufeifei 阅读(...) 评论(...) 编辑 收藏