Автор проблеми: | Хасан Салех (MathModel) |
Підготовлено: | Хасан Салех (MathModel) |
Редаговано: | Хасан Салех (MathModel) |
Рішення
У Tree, вузол має нащадків та 2u+1. Глибина — це кількість ребер, щоб досягти , тому
Отже, всі вузли глибини формують інтервал
Нам дано та запити (a,b,c,d), і ми повинні підрахувати впорядковані пари такі, що: 1\le u\le v\le n, є предком , \mathrm{depth}(u)\in[a,b], \mathrm{depth}(v)\in[c,d].
Фіксуємо \mathrm{depth}(v)=y. Тоді має точно одного предка на кожній глибині 0,1,\dots,y, тому кількість предків з глибиною в дорівнює кількості цілих чисел в
що дорівнює
Всі вузли однієї й тієї ж глибини вносять однакове , отже, відповідь на запит стає
де — це кількість вузлів глибини серед .
Нехай D=\lfloor \log_2 n \rfloor буде максимальною глибиною. Для 0\le y < D рівень заповнений:
а останній рівень частковий:
Для кожного запиту, якщо c>D, відповідь дорівнює , і ми обмежуємо d=\min(d,D). Потім ми ітеруємо y=c..d: нехай mx=\min(b,y), якщо mx\ge a, додаємо (mx-a+1)\cdot \mathrm{cnt}[y].
Оскільки D\le 56 для n\le 10^{17}, кожен запит є , тобто близько операцій, що швидко для 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";
}
}