[题解]2024CCPC郑州站——Z-order Curve

题目简介

  • 题源:L. Z-order Curve | GYM
  • 题意:对于如下Z曲线,给定曲线端点 [ L , R ] [L,R] [L,R],找出最小的 L ′ L^{'} L′,使得 [ L ′ , R ′ − L + 1 ] [L^{'},R^{'}-L+1] [L′,R′−L+1] 与 [ L , R ] [L,R] [L,R] 曲线形状相同。注意 [ L , R ] [L,R] [L,R]为有向线段。
  • 数据范围: 0 ≤ L , R ≤ 1 0 18 0\le L,R\le 10^{18} 0≤L,R≤1018
  • 关键词:递归,二进制(签到)

题解1:递归

观察可知Z曲线具有自相似性。每一个大小为 2 k 2^k 2k的大Z曲线,均由4个大小为 2 k − 1 2^{k-1} 2k−1的小Z曲线拼接而成,我们称其分别为左上、右上、左下、右下。这天然启发我们使用递归求解。具体而言:

  • 若 [ L , R ] [L,R] [L,R] 位于同一层,则可通过取模,将其平移到位于左上角的小Z曲线中,同时向下一层递归;
  • 否则,代表已找到能表示出该曲线形状的最小Z曲线,无法再继续分解。此时左端点即为答案。

观察到 R ≤ 1 0 18 R\le 10^{18} R≤1018,使用换底公式求得其 < 2 60 <2^{60} <260,故直接从第60层向下递归。复杂度 O ( log ⁡ R ) O(\log R) O(logR)。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
#define int i64
#define endl '\n'
int solve(int L,int R,int k) {
    int size=1LL<<k;
    if (L/size!=R/size) return L;
    return solve(L%size,R%size,k-1);
}
signed main() {
    ios::sync_with_stdio(0),cin.tie(0);
    int t;cin>>t;
    while (t--) {
        int l,r;cin>>l>>r;
        cout<<solve(l,r,60)<<endl;
    }
    return 0;
}

题解2:二进制

前置知识:莫顿码的构成,四叉树。此思想理解非常困难,博主太菜了,暂时搁置。

相关推荐
消失的旧时光-19433 分钟前
C++ 函数参数传递方式总结:什么时候用值传递、引用、const 引用?
开发语言·c++
一匹电信狗5 分钟前
【C++】CPU的局部性原理
开发语言·c++·系统架构·学习笔记·c++11·智能指针·新特性
皮皮哎哟7 分钟前
冒泡排序与数组传递全解析 一维二维指针数组及二级指针应用指南
c语言·算法·冒泡排序·二维数组·指针数组·传参·二级指针
m0_561359678 分钟前
C++代码冗余消除
开发语言·c++·算法
会开花的二叉树13 分钟前
吃透Reactor多线程:EventLoop_Channel_ThreadPool协作原理
开发语言·c++·tcp/ip·servlet
Jm_洋洋15 分钟前
【C++进阶】虚函数、虚表与虚指针:多态底层机制剖析
java·开发语言·c++
近津薪荼19 分钟前
优选算法——滑动窗口1(单调性)
c++·学习·算法
头发还没掉光光19 分钟前
Linux 高级 IO 深度解析:从 IO 本质到 epoll全面讲解
linux·服务器·c语言·c++
爱装代码的小瓶子20 分钟前
【C++与Linux基础】进程如何打开磁盘文件:从open()到文件描述符的奇妙旅程(更多源码讲解)
linux·开发语言·c++
diediedei21 分钟前
嵌入式C++驱动开发
开发语言·c++·算法