F. Counting Necessary Nodes 【Codeforces Round 1009 (Div. 3)】
Codeforces Round 1009 (Div. 3)
思路:
很有线段树美感的题。
- 初始假设:假设每个1x1的正方形都是叶子节点,总数为矩形的面积。
- 层级合并:从小到大逐层检查是否存在可以覆盖多个小节点的正方形。每个层级的正方形边长为2的幂次。
- 覆盖计算:
• 对每个层级,计算该层级下可以覆盖的完整正方形数目。
• 每个大正方形可以减少3个小节点(用1个大节点代替4个小节点,节省3个)。 - 终止条件:当当前层级的正方形无法覆盖任何区域时停止。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define int long long
#define pb push_back
#define pii pair<int,int>
#define FU(i, a, b) for(int i = (a); i <= (b); ++ i)
#define FD(i, a, b) for(int i = (a); i >= (b); -- i)
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
void solve() {
int l1,r1,l2,r2;
cin>>l1>>r1>>l2>>r2;
int cnt = (r1-l1)*(r2-l2);
for(int i=1;i<=20;i++){
int t=1<<i;
int lx=(l1>>i<<i);
if(l1 %t!=0)lx+=t;
int ly=(l2>>i<<i);
if(l2 %t!=0)ly+=t;
int rx=r1>>i<<i;
int ry=r2>>i<<i;
// cout<<lx<<" "<<rx<<" "<<ly<<" "<<ry<<endl;
if(lx>=rx || ly>=ry)break;
cnt-=3*(rx-lx)/t *(ry-ly)/t;
}
cout<<cnt<<endl;
}
signed main() {
cin.tie(0)->ios::sync_with_stdio(0);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}