2Tree Queries#12314

2Tree Queries (Çözgüdiň düşündirişi)

Problem Author:

Hasan Saleh (MathModel)

Prepared by:

Hasan Saleh (MathModel)

Edited by:

Hasan Saleh (MathModel)

Solution

In the Tree, node has children and 2u+1. The depth is the number of edges to reach , so

\mathrm{depth}(x)=\lfloor \log_2 x \rfloor.

Hence all nodes of depth form the interval

[2^y,\;2^{y+1}-1].

We are given and queries (a,b,c,d), and we must count ordered pairs such that: 1\le u\le v\le n, is an ancestor of , \mathrm{depth}(u)\in[a,b], \mathrm{depth}(v)\in[c,d].

Fix \mathrm{depth}(v)=y. Then has exactly one ancestor at each depth 0,1,\dots,y, so the number of ancestors with depth in equals the number of integers in

[a,b]\cap[0,y],

which is

f(y)=\max\bigl(0,\;\min(b,y)-a+1\bigr).

All nodes of the same depth contribute the same , thus the query answer becomes

\sum_{y=c}^{d} \mathrm{cnt}[y]\cdot f(y),

where is the number of nodes of depth among .

Let D=\lfloor \log_2 n \rfloor be the maximum depth. For 0\le y < D the level is full:

\mathrm{cnt}[y]=2^y,

and the last level is partial:

\mathrm{cnt}[D]=n-2^D+1.

For each query, if c>D the answer is , and we clamp d=\min(d,D). Then we iterate y=c..d: let mx=\min(b,y), if mx\ge a add (mx-a+1)\cdot \mathrm{cnt}[y].

Since D\le 56 for n\le 10^{17}, each query is , i.e. about operations, which is fast for q\le 10^6.

#include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    long long n; int q;
    cin>>n>>q;

    int D=63-__builtin_clzll((unsigned long long)n);

    vector<long long> cnt(D+1);
    for(int y=0;y<D;y++)cnt[y]=1LL<<y;
    cnt[D]=n-(1LL<<D)+1;

    while(q--){
        long long a,b,c,d;
        cin>>a>>b>>c>>d;

        if(c>D){cout<<0<<"\n";continue;}
        if(d>D)d=D;

        long long ans=0;
        for(long long y=c;y<=d;y++){
            long long mx=min(b,y);
            if(mx>=a)ans+=(mx-a+1)*cnt[y];
        }
        cout<<ans<<"\n";
    }
}