Codeforces Round #447 (Div. 2) D. Ralph And His Tour in Binary Country 二叉树、预处理、二分、数据结构

来源:互联网 发布:王者荣耀用java还是c 编辑:程序博客网 时间:2024/06/14 01:48

D. Ralph And His Tour in Binary Country
time limit per test
2.5 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

Ralph is in the Binary Country. The Binary Country consists of n cities and (n - 1) bidirectional roads connecting the cities. The roads are numbered from 1 to (n - 1), the i-th road connects the city labeled  (here ⌊ x denotes the x rounded down to the nearest integer) and the city labeled (i + 1), and the length of the i-th road is Li.

Now Ralph gives you m queries. In each query he tells you some city Ai and an integer Hi. He wants to make some tours starting from this city. He can choose any city in the Binary Country (including Ai) as the terminal city for a tour. He gains happiness (Hi - L) during a tour, where L is the distance between the city Ai and the terminal city.

Ralph is interested in tours from Ai in which he can gain positive happiness. For each query, compute the sum of happiness gains for all such tours.

Ralph will never take the same tour twice or more (in one query), he will never pass the same city twice or more in one tour.

Input

The first line contains two integers n and m (1 ≤ n ≤ 1061 ≤ m ≤ 105).

(n - 1) lines follow, each line contains one integer Li (1 ≤ Li ≤ 105), which denotes the length of the i-th road.

m lines follow, each line contains two integers Ai and Hi (1 ≤ Ai ≤ n0 ≤ Hi ≤ 107).

Output

Print m lines, on the i-th line print one integer — the answer for the i-th query.

Examples
input
2 251 82 4
output
114
input
6 4211322 41 33 21 7
output
116328
Note

Here is the explanation for the second sample.

Ralph's first query is to start tours from city 2 and Hi equals to 4. Here are the options:

  • He can choose city 5 as his terminal city. Since the distance between city 5 and city 2 is 3, he can gain happiness 4 - 3 = 1.
  • He can choose city 4 as his terminal city and gain happiness 3.
  • He can choose city 1 as his terminal city and gain happiness 2.
  • He can choose city 3 as his terminal city and gain happiness 1.
  • Note that Ralph can choose city 2 as his terminal city and gain happiness 4.
  • Ralph won't choose city 6 as his terminal city because the distance between city 6 and city 2 is 5, which leads to negative happiness for Ralph.

So the answer for the first query is 1 + 3 + 2 + 1 + 4 = 11.



Source

Codeforces Round #447 (Div. 2)


My Solution

题意:给出一颗二叉树,每条边有一个权值,q个询问,每次询问以x为起点,到yi点,求max(H - xyi, 0)求和。


二叉树、预处理、二分、数据结构

先在每个节点维护 该点 到 以其为根的点 的距离,且排序(笔者用的c++的sort所以比归并排序多出一个logn),

并维护n个前缀和。这里时间复杂度 O(nlognlogn) 空间复杂度 O(nlogn)。

然后查询的时候,对于x点进行二分可以找出答案,然后向上回溯,且维护一个变量sumlx为其祖先节点到x的距离。

查找该节点所在的链的隔壁的子树,进行二分可以找出符合条件的点,并且加上该根节点。一直回溯到x的根为止。

故查询也是nlognlogn的。

//这里由于用的c++的sort,用 ios::sync_with_stdio(false); cin.tie(0);和cin、cout,依然会超时,换成printf和scanf就可以过。

时间复杂度 O((m+n)*lognlogn)

空间复杂度 O(nlogn)


#include <iostream>#include <cstdio>#include <vector>#include <algorithm>using namespace std;typedef long long LL;const int MAXN = 1e6 + 8, MAXM = 1e5 + 8;vector<LL> val[MAXN], sum[MAXN];LL L[MAXN], n;inline void dfs(int u){    if(u > n) return;    //    dfs(u<<1);    dfs(u<<1|1);    int sz, i;    if((u<<1) <= n){        sz = val[u<<1].size();        for(i = 0; i < sz; i++){            val[u].push_back(val[u<<1][i] + L[u<<1]);        }    }    if((u<<1|1) <= n){        sz = val[u<<1|1].size();        for(i = 0; i < sz; i++){            val[u].push_back(val[u<<1|1][i] + L[u<<1|1]);        }    }    val[u].push_back(0);    sort(val[u].begin(), val[u].end());    sz = val[u].size();    sum[u].push_back(val[u][0]);    for(i = 1; i < sz; i++){        sum[u].push_back(val[u][i] + sum[u][i-1]);    }}int main(){    #ifdef LOCAL    freopen("d.txt", "r", stdin);    //freopen("d.out", "w", stdout);    int T = 3;    while(T--){    #endif // LOCAL    //ios::sync_with_stdio(false); cin.tie(0);    int m, i;    LL x, h, sumlx, ans, ansind, cpy;    cin >> n >> m;    for(i = 1; i < n; i++){        scanf("%I64d", &L[i+1]);    }    dfs(1);    int l, r, mid;    while(m--){        //cin >> x >> h;        scanf("%I64d%I64d", &x, &h);        sumlx = 0; ans = 0;        //        l = -1, r = val[x].size(), ansind = -1;        while(l + 1 < r){            mid = (l + r) >> 1;            //cout << "??" << mid << "??" << endl;            if(val[x][mid] <= h){                l = mid;                ansind = mid;            }            else{                r = mid;            }        }        //cout << "??" << ansind << "??" << endl;        if(ansind != -1) ans += h*(ansind + 1) - sum[x][ansind];        sumlx += L[x];        cpy = x;        x >>= 1;        while(x){            //            cpy = cpy == (x<<1) ? (x<<1|1) : (x<<1);            l = -1, r = val[cpy].size(), ansind = -1;            while(cpy <= n && l + 1 < r){                mid = (l + r) >> 1;                if(val[cpy][mid] + sumlx + L[cpy] <= h){                    l = mid;                    ansind = mid;                }                else{                    r = mid;                }            }            //cout << "??" << ansind << "??";            if(ansind != -1) ans += (h - sumlx - L[cpy])*(ansind + 1) - sum[cpy][ansind];            ans += max(0ll, h - sumlx);            if(h - sumlx <= 0) break; //!            sumlx += L[x];            cpy = x;            x >>= 1;        }        //cout << ans << "\n";        printf("%I64d\n", ans);    }    #ifdef LOCAL    for(i = 1; i <= n; i++){        val[i].clear();        sum[i].clear();    }    cout << endl;    }    #endif // LOCAL    return 0;}



  Thank you!

                                                                                                                                             ------from ProLights

阅读全文
0 0
原创粉丝点击