zoukankan      html  css  js  c++  java
  • 【Luogu】P6232 [eJOI2019]挂架 题解

    这道题跟CSP/S 2019 D1T1有点像。

    我们先来模拟一下 (n=4) 的情况,

    不难得出,最后的衣架挂钩顺序:

    下标:  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
    顺序:  1  9  5 13  3 11  7 15  2 10  6 14  4 12  8 16
    

    我们发现,得到的顺序构成的序列中左半部分全是奇数,右半部分全是偶数。我们把它分开:

    1 9 5 13 3 11 7 15
    2 10 6 14 4 12 8 16
    

    奇数部分每个数 (+1)(div 2),偶数部分每个数 (div 2),可以得到:

    1 5 3 7 2 6 4 8
    1 5 3 7 2 6 4 8
    

    我们惊喜地发现,上下部分变得一样了!不仅如此,这还恰巧是 (n=3) 的情况!

    所以,我们自然而然想到递归。

    如果深度已经是 (n-1) 了,直接将答案加上当前序号;(第一层深度为(0)

    如果当前序号为奇数,即在左半部分,则把它 (+1)(div 2),继续递归;

    如果当前序号为偶数,即在右半部分,则把它 (div 2),同时答案加上 (2^{n-depth-1})(左半部分的长度),继续递归。

    时间复杂度(O(nlogn)),当然你预处理幂的话就是(O(n))了。

    (Code:)(极为精简的代码)

    #include <bits/stdc++.h>
    #define int long long
    int n,k,MOD=1e9+7;
    int qpow(int x,int y){ //快速幂
        int res=1;
        while(y){
            if(y&1) res=(res*x)%MOD;
            x=(x*x)%MOD;y>>=1;
        }
        return res;
    }
    int dfs(int x,int dep) {
        //我这里深度是从1开始算的,所以下面调用快速幂时略有不同
        return dep==n?x:(x%2?dfs((x+1)/2,dep+1):(dfs(x/2,dep+1)+qpow(2,n-dep))%MOD);
    }
    signed main(){
        std::cin>>n>>k;std::cout<<dfs(k,1)%MOD<<std::endl;
        return 0;
    }
    

    点个赞再走吧!

  • 相关阅读:
    倒排索引压缩
    记一次java内存溢出的解决过程
    [译]ES读写文档时shard-replication模型
    [转载]抓包工具Charles乱码解决办法
    Mac 快捷键整理(不定期更新)
    高效能人士执行的四原则(2017-12-15)
    scala sbt 添加国内镜像
    maven工程小红叉处理方法
    系统管理中 bash shell 脚本常用方法总结
    scala 2.11报错error: not found: type Application
  • 原文地址:https://www.cnblogs.com/acceptedzhs/p/13032385.html
Copyright © 2011-2022 走看看