Codeforces Global Round 1

蒟蒻的再一次血崩

A. Parity

Description:

You are given an integer n n n ( n ≥ 0 n \ge 0 n0) represented with k k k digits in base (radix) b b b. So,
n = a 1 ⋅ b k − 1 + a 2 ⋅ b k − 2 + … a k − 1 ⋅ b + a k . n = a_1 \cdot b^{k-1} + a_2 \cdot b^{k-2} + \ldots a_{k-1} \cdot b + a_k. n=a1bk1+a2bk2+ak1b+ak.
For example, if b = 17 , k = 3 b=17, k=3 b=17,k=3 and a = [ 11 , 15 , 7 ] a=[11, 15, 7] a=[11,15,7] then n = 11 ⋅ 1 7 2 + 15 ⋅ 17 + 7 = 3179 + 255 + 7 = 3441 n=11\cdot17^2+15\cdot17+7=3179+255+7=3441 n=11172+1517+7=3179+255+7=3441.
Determine whether n n n is even or odd.

Input:

The first line contains two integers b b b and k k k ( 2 ≤ b ≤ 100 2\le b\le 100 2b100, 1 ≤ k ≤ 1 0 5 1\le k\le 10^5 1k105) — the base of the number and the number of digits.
The second line contains k k k integers a 1 , a 2 , … , a k a_1, a_2, \ldots, a_k a1,a2,,ak ( 0 ≤ a i < b 0\le a_i < b 0ai<b) — the digits of n n n.
The representation of n n n contains no unnecessary leading zero. That is, a 1 a_1 a1 can be equal to 0 0 0 only if k = 1 k = 1 k=1.

Output

Print “even” if n n n is even, otherwise print “odd”.
You can print each letter in any case (upper or lower).

Sample Input:

13 3
3 2 7

Sample Output:

even

Sample Input:

10 9
1 2 3 4 5 6 7 8 9

Sample Output:

odd

Sample Input:

99 5
32 92 85 74 4

Sample Output:

odd

Sample Input:

2 2
1 0

Sample Output:

even

题目链接

根据奇偶相加为奇,奇奇、偶偶相加为偶依次判断即可

AC代码:

#include 
using namespace std;

const int maxn = 1e5 + 5;

int B, K;
int A[maxn];
bool Cur;

int main(int argc, char *argv[]) {
    scanf("%d%d", &B, &K);
    Cur = true;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &A[i]);
        if (i == K && Cur && (A[i] & 1)) {
            Cur = false;
            continue;
        }
        if ((A[i] & 1) && (B & 1)) Cur = !Cur;
    }
    if (Cur) printf("even\n");
    else printf("odd\n");
    return 0;
}

B. Tape

Description:

You have a long stick, consisting of m m m segments enumerated from 1 1 1 to m m m. Each segment is 1 1 1 centimeter long. Sadly, some segments are broken and need to be repaired.
You have an infinitely long repair tape. You want to cut some pieces from the tape and use them to cover all of the broken segments. To be precise, a piece of tape of integer length t t t placed at some position s s s will cover segments s , s + 1 , … , s + t − 1 s, s+1, \ldots, s+t-1 s,s+1,,s+t1.
You are allowed to cover non-broken segments; it is also possible that some pieces of tape will overlap.
Time is money, so you want to cut at most k k k continuous pieces of tape to cover all the broken segments. What is the minimum total length of these pieces?

Input:

The first line contains three integers n n n, m m m and k k k ( 1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105, n ≤ m ≤ 1 0 9 n \le m \le 10^9 nm109, 1 ≤ k ≤ n 1 \le k \le n 1kn) — the number of broken segments, the length of the stick and the maximum number of pieces you can use.
The second line contains n n n integers b 1 , b 2 , … , b n b_1, b_2, \ldots, b_n b1,b2,,bn ( 1 ≤ b i ≤ m 1 \le b_i \le m 1bim) — the positions of the broken segments. These integers are given in increasing order, that is, b 1 < b 2 < … < b n b_1 < b_2 < \ldots < b_n b1<b2<<bn.

Output

Print the minimum total length of the pieces.

Sample Input:

4 100 2
20 30 75 80

Sample Output:

17

Sample Input:

5 100 3
1 2 4 60 87

Sample Output:

6

题目链接

差分计算每段长度,去掉最长的 k − 1 k-1 k1 段即可

AC代码:

#include 
using namespace std;

typedef long long ll;
const int maxn = 1e5 + 5;

int N, M, K;
int B[maxn];
ll Seg[maxn];
ll Ans;

int main(int argc, char *argv[]) {
    scanf("%d%d%d", &N, &M, &K);
    if (N == 1) {
        printf("1\n");
        return 0;
    }
    for (int i = 0; i < N; ++i) scanf("%d", &B[i]);
    for (int i = 1; i < N; ++i) Seg[i] = B[i] - B[i - 1];
    sort(Seg + 1, Seg + N);
    for (int i = 1; i < N - (K - 1); ++i) Ans += Seg[i];
    printf("%lld\n", Ans + K);
    return 0;
}

C. Meaningless Operations

Description:

Can the greatest common divisor and bitwise operations have anything in common? It is time to answer this question.
Suppose you are given a positive integer a a a. You want to choose some integer b b b from 1 1 1 to a − 1 a - 1 a1 inclusive in such a way that the greatest common divisor (GCD) of integers a ⊕ b a \oplus b ab and a & b a \& b a&b is as large as possible. In other words, you’d like to compute the following function:
f ( a ) = max ⁡ 0 < b < a g c d ( a ⊕ b , a & b ) . f(a) = \max_{0 < b < a}{gcd(a \oplus b, a \& b)}. f(a)=0<b<amaxgcd(ab,a&b).
Here ⊕ \oplus denotes the bitwise XOR operation, and & \& & denotes the bitwise AND operation.
The greatest common divisor of two integers x x x and y y y is the largest integer g g g such that both x x x and y y y are divided by g g g without remainder.
You are given q q q integers a 1 , a 2 , … , a q a_1, a_2, \ldots, a_q a1,a2,,aq. For each of these integers compute the largest possible value of the greatest common divisor (when b b b is chosen optimally).

Input:

The first line contains an integer q q q ( 1 ≤ q ≤ 1 0 3 1 \le q \le 10^3 1q103) — the number of integers you need to compute the answer for.
After that q q q integers are given, one per line: a 1 , a 2 , … , a q a_1, a_2, \ldots, a_q a1,a2,,aq ( 2 ≤ a i ≤ 2 25 − 1 2 \le a_i \le 2^{25} - 1 2ai2251) — the integers you need to compute the answer for.

Output

For each integer, print the answer in the same order as the integers are given in input.

Sample Input:

3
2
3
5

Sample Output:

3
1
7

题目链接

观察易得若 n ≠ 2 x − 1 n\neq2^{x}-1 n̸=2x1 则其结果在二进制上与 n n n 等长且每一位均为 1 1 1

n = 2 x − 1 n=2^{x}-1 n=2x1 则打表特判即可

AC代码:

#include 
using namespace std;

typedef long long ll;

int T;
ll N;
ll Len;
map<ll, ll> Mp;

int main(int argc, char *argv[]) {
    Mp[3] = 1; Mp[7] = 1; Mp[15] = 5; Mp[31] = 1; Mp[63] = 21;
    Mp[127] = 1; Mp[255] = 85; Mp[511] = 73; Mp[1023] = 341;
    Mp[2047] = 89; Mp[4095] = 1365; Mp[8191] = 1;  Mp[16383] = 5461;
    Mp[32767] = 4681; Mp[65535] = 21845; Mp[131071] = 1;
    Mp[262143] = 87381; Mp[524287] = 1; Mp[1048575] = 349525;
    Mp[2097151] = 299593; Mp[4194303] = 1398101; Mp[8388607] = 178481;
    Mp[16777215] = 5592405; Mp[33554431] = 1082401;
    scanf("%d\n", &T);
    for (int Case = 1; Case <= T; ++Case) {
        scanf("%lld", &N);
        Len = log2(N) + 1;
        if (Mp[N]) printf("%lld\n", Mp[N]);
        else printf("%lld\n", (1ll << Len) - 1);
    }
    return 0;
}

D. Jongmah

Description:

You are playing a game of Jongmah. You don’t need to know the rules to solve this problem. You have n n n tiles in your hand. Each tile has an integer between 1 1 1 and m m m written on it.
To win the game, you will need to form some number of triples. Each triple consists of three tiles, such that the numbers written on the tiles are either all the same or consecutive. For example, 7 , 7 , 7 7, 7, 7 7,7,7 is a valid triple, and so is 12 , 13 , 14 12, 13, 14 12,13,14, but 2 , 2 , 3 2,2,3 2,2,3 or 2 , 4 , 6 2,4,6 2,4,6 are not. You can only use the tiles in your hand to form triples. Each tile can be used in at most one triple.
To determine how close you are to the win, you want to know the maximum number of triples you can form from the tiles in your hand.

Input:

The first line contains two integers integer n n n and m m m ( 1 ≤ n , m ≤ 1 0 6 1 \le n, m \le 10^6 1n,m106) — the number of tiles in your hand and the number of tiles types.
The second line contains integers a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an ( 1 ≤ a i ≤ m 1 \le a_i \le m 1aim), where a i a_i ai denotes the number written on the i i i-th tile.

Output

Print one integer: the maximum number of triples you can form.

Sample Input:

10 6
2 3 3 3 4 4 4 5 5 6

Sample Output:

3

Sample Input:

12 6
1 5 3 3 3 4 3 5 3 2 3 3

Sample Output:

3

Sample Input:

13 5
1 1 5 1 2 3 3 2 4 2 3 4 5

Sample Output:

4

题目链接

求一个数列中得数字可以组成多少连续或相同数字的三元组

构造三元组时不存在 3 3 3 组或以上个 [ x − 1 , x , x + 1 ] [x-1,x,x+1] [x1,x,x+1] ,因为若存在则我们可以拆分为 [ x − 1 , x − 1. x − 1 ] , [ x , x , x ] , [ x + 1 , x + 1 , x + 1 ] [x-1,x-1.x-1],[x,x,x],[x+1,x+1,x+1] [x1,x1.x1],[x,x,x],[x+1,x+1,x+1]

考虑动态规划, d p [ a ] [ i ] [ j ] dp[a][i][j] dp[a][i][j] 表示 [ 1 , a ] [1,a] [1,a] 中有 i i i 个形如 [ a − 1 , a , a + 1 ] [a-1,a,a+1] [a1,a,a+1] 的三元组和 j j j 个形如 [ a , a + 1 , a + 2 ] [a,a+1,a+2] [a,a+1,a+2] 的三元组

枚举 k k k 为形如 [ a + 1 , a + 2 , a + 3 ] [a+1,a+2,a+3] [a+1,a+2,a+3] 的三元组,把剩下的 a + 1 a+1 a+1 变为形如 [ a + 1 , a + 1 , a + 1 ] [a+1,a+1,a+1] [a+1,a+1,a+1] 的三元组即可将 d p [ a ] [ i ] [ j ] dp[a][i][j] dp[a][i][j] 转移至 d p [ a + 1 ] [ j ] [ k ] dp[a+1][j][k] dp[a+1][j][k]

AC代码:

#include 
using namespace std;

const int maxn = 1e6 + 5;

int N, M;
int Cnt[maxn];
int Dp[maxn][5][5];

int main(int argc, char *argv[]) {
    scanf("%d%d", &N, &M);
    for (int i = 1, X; i <= N; ++i) {
        scanf("%d", &X);
        Cnt[X]++;
    }
    for (int a = 0; a <= M; ++a) {
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                for (int k = 0; k < 3; ++k) {
                    if (i + j + k <= Cnt[a]) {
                        Dp[a + 1][j][k] = max(Dp[a + 1][j][k], Dp[a][i][j] + k + (Cnt[a] - i - j - k) / 3);
                    }
                }
            }
        }
    }
    printf("%d\n", Dp[M + 1][0][0]);
    return 0;
}

E. Magic Stones

Description:

Grigory has n n n magic stones, conveniently numbered from 1 1 1 to n n n. The charge of the i i i-th stone is equal to c i c_i ci.
Sometimes Grigory gets bored and selects some inner stone (that is, some stone with index i i i, where 2 ≤ i ≤ n − 1 2 \le i \le n - 1 2in1), and after that synchronizes it with neighboring stones. After that, the chosen stone loses its own charge, but acquires the charges from neighboring stones. In other words, its charge c i c_i ci changes to c i ′ = c i + 1 + c i − 1 − c i c_i' = c_{i + 1} + c_{i - 1} - c_i ci=ci+1+ci1ci.
Andrew, Grigory’s friend, also has n n n stones with charges t i t_i ti. Grigory is curious, whether there exists a sequence of zero or more synchronization operations, which transforms charges of Grigory’s stones into charges of corresponding Andrew’s stones, that is, changes c i c_i ci into t i t_i ti for all i i i?

Input:

The first line contains one integer n n n ( 2 ≤ n ≤ 1 0 5 2 \le n \le 10^5 2n105) — the number of magic stones.
The second line contains integers c 1 , c 2 , … , c n c_1, c_2, \ldots, c_n c1,c2,,cn ( 0 ≤ c i ≤ 2 ⋅ 1 0 9 0 \le c_i \le 2 \cdot 10^9 0ci2109) — the charges of Grigory’s stones.
The second line contains integers t 1 , t 2 , … , t n t_1, t_2, \ldots, t_n t1,t2,,tn ( 0 ≤ t i ≤ 2 ⋅ 1 0 9 0 \le t_i \le 2 \cdot 10^9 0ti2109) — the charges of Andrew’s stones.

Output

If there exists a (possibly empty) sequence of synchronization operations, which changes all charges to the required ones, print “Yes”.
Otherwise, print “No”.

Sample Input:

4
7 2 4 12
7 15 10 12

Sample Output:

Yes

Sample Input:

3
4 4 4
1 2 3

Sample Output:

No

题目链接

两个数列 c c c t t t ,可以操作 c c c 数列中任意一个数 c i c_i ci 改变为 c i + 1 + c i − 1 − c i c_{i+1}+c_{i-1}-c_{i} ci+1+ci1ci ,判断经过操作后数列 c c c 能否改变为数列 t t t

设数列 c c c [ c 1 , c 2 , c 3 ] [c_1,c_2,c_3] [c1,c2,c3] ,其差分数组 d i f f diff diff [ d i f f 1 , d i f f 2 ] ( d i f f 1 = c 2 − c 1 , d i f f 2 = c 3 − c 2 ) [diff_1,diff_2](diff_1=c_2-c_1,diff_2=c_3-c_2) [diff1,diff2](diff1=c2c1,diff2=c3c2)

若将数列 c c c c 2 c_2 c2 改变为 c 1 + c 3 − c 2 c_1+c_3-c_2 c1+c3c2 那么 c c c 现在为 [ c 1 , c 1 + c 3 − c 2 , c 3 ] [c_1,c_1+c_3-c_2,c_3] [c1,c1+c3c2,c3] ,则其差分数组为 [ d i f f 2 , d i f f 1 ] [diff_2,diff_1] [diff2,diff1]

因为 ( c 1 + c 3 − c 2 ) − c 1 = c 3 − c 2 = d i f f 2 , c 3 − ( c 1 + c 3 − c 2 ) = c 2 − c 1 = d i f f 1 (c_1+c_3-c_2)-c_1=c_3-c_2=diff_2,c_3-(c_1+c_3-c_2)=c_2-c_1=diff_1 (c1+c3c2)c1=c3c2=diff2,c3(c1+c3c2)=c2c1=diff1 ,所以通过操作仅可调换操作数左右差分数组的次序,那么就可以根据差分数组是否相等即可判断数列 c c c 是否可以通过操作改变为数列 t t t

AC代码:

#include 
using namespace std;

typedef long long ll;
const int maxn = 1e5 + 5;

int N;
ll C[maxn];
ll T[maxn];
ll CDiff[maxn];
ll TDiff[maxn];

int main(int argc, char *argv[]) {
    scanf("%d", &N);
    for (int i = 1; i <= N; ++i) scanf("%lld", &C[i]);
    for (int i = 1; i <= N; ++i) scanf("%lld", &T[i]);
    if (C[1] != T[1] || C[N] != T[N]) {
        printf("No\n");
        return 0;
    }
    for (int i = 2; i <= N; ++i) CDiff[i] = C[i] - C[i - 1];
    for (int i = 2; i <= N; ++i) TDiff[i] = T[i] - T[i - 1];
    sort(CDiff + 2, CDiff + N + 1);
    sort(TDiff + 2, TDiff + N + 1);
    for (int i = 2; i <= N; ++i) {
        if (CDiff[i] != TDiff[i]) {
            printf("No\n");
            return 0;
        }
    }
    printf("Yes\n");
    return 0;
}

F. Nearest Leaf

Description:

Let’s define the Eulerian traversal of a tree (a connected undirected graph without cycles) as follows: consider a depth-first search algorithm which traverses vertices of the tree and enumerates them in the order of visiting (only the first visit of each vertex counts). This function starts from the vertex number 1 1 1 and then recursively runs from all vertices which are connected with an edge with the current vertex and are not yet visited in increasing numbers order. Formally, you can describe this function using the following pseudocode:

next_id = 1
id = array of length n filled with -1
visited = array of length n filled with false

function dfs(v):
    visited[v] = true
    id[v] = next_id
    next_id += 1
    for to in neighbors of v in increasing order:
        if not visited[to]:
            dfs(to)

You are given a weighted tree, the vertices of which were enumerated with integers from 1 1 1 to n n n using the algorithm described above.
A leaf is a vertex of the tree which is connected with only one other vertex. In the tree given to you, the vertex 1 1 1 is not a leaf. The distance between two vertices in the tree is the sum of weights of the edges on the simple path between them.
You have to answer q q q queries of the following type: given integers v v v, l l l and r r r, find the shortest distance from vertex v v v to one of the leaves with indices from l l l to r r r inclusive.

Input:

The first line contains two integers n n n and q q q ( 3 ≤ n ≤ 500   000 , 1 ≤ q ≤ 500   000 3 \leq n \leq 500\,000, 1 \leq q \leq 500\,000 3n500000,1q500000) — the number of vertices in the tree and the number of queries, respectively.
The ( i − 1 ) (i - 1) (i1)-th of the following n − 1 n - 1 n1 lines contains two integers p i p_i pi and w i w_i wi ( 1 ≤ p i < i , 1 ≤ w i ≤ 1 0 9 1 \leq p_i < i, 1 \leq w_i \leq 10^9 1pi<i,1wi109), denoting an edge between vertices p i p_i pi and i i i with the weight w i w_i wi.
It’s guaranteed that the given edges form a tree and the vertices are enumerated in the Eulerian traversal order and that the vertex with index 1 1 1 is not a leaf.
The next q q q lines describe the queries. Each of them contains three integers v i v_i vi, l i l_i li, r i r_i ri ( 1 ≤ v i ≤ n , 1 ≤ l i ≤ r i ≤ n 1 \leq v_i \leq n, 1 \leq l_i \leq r_i \leq n 1vin,1lirin), describing the parameters of the query. It is guaranteed that there is at least one leaf with index x x x such that l i ≤ x ≤ r i l_i \leq x \leq r_i lixri.

Output

Output q q q integers — the answers for the queries in the order they are given in the input.

Sample Input:

5 3
1 10
1 1
3 2
3 3
1 1 5
5 4 5
4 1 2

Sample Output:

3
0
13

Sample Input:

5 3
1 1000000000
2 1000000000
1 1000000000
1 1000000000
3 4 5
2 1 5
2 4 5

Sample Output:

3000000000
1000000000
2000000000

Sample Input:

11 8
1 7
2 1
1 20
1 2
5 6
6 2
6 3
5 1
9 10
9 11
5 1 11
1 1 4
9 4 8
6 1 4
9 7 11
9 10 11
8 1 11
11 4 5

Sample Output:

8
8
9
16
9
10
0
34

题目链接

一棵以 1 1 1 为根的 n n n 个节点有根带权树,对每次询问 v v v l l l r r r 求以 v v v 为起点到编号为 [ l , r ] [l,r] [l,r] 内叶子节点的最近距离(题目保证 [ l , r ] [l,r] [l,r] 内至少有一个叶子节点)

发现题目树上节点编号正好对应dfs序编号,所以可以利用dfs序求出每个节点到根节点的距离(题目只要求叶子节点所以非叶子节点的距离直接设为 inf ⁡ \inf inf 即可)并用线段树维护

考虑离线处理每次询问

由根节点开始dfs整棵树,假设dfs枚举节点为 c u r cur cur 对于每个 c u r cur cur 为查询起点的询问其结果为 [ l , r ] [l,r] [l,r] 距离中的最小值,每次向下搜索到 s o n [ c u r ] son[cur] son[cur] s o n [ c u r ] son[cur] son[cur] 其子树中节点两两之间距离减 2 × d i s ( c u r , s o n [ c u r ] ) 2\times dis(cur, son[cur]) 2×dis(cur,son[cur]) ,这里利用dfs序加线段树区间修改即可实现

此题若用链式前向星建图则节点编号顺序不对应

AC代码:

#include 
using namespace std;

typedef long long ll;
const ll INF = 1e18;
const int maxn = 5e5 + 5;

//------Graph------
struct Edge {int V, Weight;};
vector<Edge> edges[maxn];

//------Segment Tree----
ll Val[maxn];

struct SegmentTree {
    ll Dis[maxn << 2];
    ll Lazy[maxn << 2];

    void PushUp(int Root) {
        Dis[Root] = min(Dis[Root << 1], Dis[Root << 1 | 1]);
    }

    void PushDown(int Root) {
        if (!Lazy[Root]) return;
        Lazy[Root << 1] += Lazy[Root];
        Lazy[Root << 1 | 1] += Lazy[Root];
        Dis[Root << 1] += Lazy[Root];
        Dis[Root << 1 | 1] += Lazy[Root];
        Lazy[Root] = 0;
    }

    void Build(int Left, int Right, int Root) {
        if (Left == Right) {
            Dis[Root] = Val[Left];
            return;
        }
        int Mid = (Left + Right) >> 1;
        Build(Left, Mid, Root << 1);
        Build(Mid + 1, Right, Root << 1 | 1);
        PushUp(Root);
    }

    void Update(int OperateLeft, int OperateRight, int Value,
                int Left, int Right, int Root) {
        if (OperateLeft <= Left && OperateRight >= Right) {
            Lazy[Root] += Value;
            Dis[Root] += Value;
            return;
        }
        PushDown(Root);
        int Mid = (Left + Right) >> 1;
        if (OperateLeft <= Mid) Update(OperateLeft, OperateRight, Value, Left, Mid, Root << 1);
        if (OperateRight > Mid) Update(OperateLeft, OperateRight, Value, Mid + 1, Right, Root << 1 | 1);
        PushUp(Root);
    }

    ll Query(int OperateLeft, int OperateRight, int Left, int Right, int Root) {
        if (OperateLeft <= Left && OperateRight >= Right) return Dis[Root];
        PushDown(Root);
        int Mid = (Left + Right) >> 1;
        ll Ans = INF;
        if (OperateLeft <= Mid) Ans = min(Ans, Query(OperateLeft, OperateRight, Left, Mid, Root << 1));
        if (OperateRight > Mid) Ans = min(Ans, Query(OperateLeft, OperateRight, Mid + 1, Right, Root << 1 | 1));
        return Ans;
    }
};

SegmentTree SGT;

//------Dfs Order------
int DfsClock;
int In[maxn];
int Out[maxn];

void DfsOrder(int Cur, ll Dis) {
    In[Cur] = ++DfsClock;
    for (auto it : edges[Cur]) DfsOrder(it.V, Dis + it.Weight);
    if (edges[Cur].empty()) Val[Cur] = Dis;
    else Val[Cur] = INF;
    Out[Cur] = DfsClock;
}

//------Query------
struct Query {int Left, Right, Id;};
vector<Query> querys[maxn];

int N, Q;
ll Ans[maxn];

void Dfs(int Cur, ll Dis) {
    for (auto it : querys[Cur]) Ans[it.Id] = SGT.Query(it.Left, it.Right, 1, N, 1) + Dis;
    for (auto it : edges[Cur]) {
        SGT.Update(In[it.V], Out[it.V], -it.Weight * 2, 1, N, 1);
        Dfs(it.V, it.Weight + Dis);
        SGT.Update(In[it.V], Out[it.V], it.Weight * 2, 1, N, 1);
    }
}

int main(int argc, char *argv[]) {
    scanf("%d%d", &N, &Q);
    for (int i = 2, U, W; i <= N; ++i) {
        scanf("%d%d", &U, &W);
        edges[U].push_back((Edge){i, W});
    }
    DfsOrder(1, 0);
    SGT.Build(1, N, 1);
    for (int i = 1, V, L, R; i <= Q; ++i) {
        scanf("%d%d%d", &V, &L, &R);
        querys[V].push_back((Query){L, R, i});
    }
    Dfs(1, 0);
    for (int i = 1; i <= Q; ++i) printf("%lld\n", Ans[i]);
    return 0;
}

你可能感兴趣的:(Codeforces Global Round 1)