「Algospot」龙曲线DRAGON

一道考验思维的好题,顺便总结求第k大问题的常规思路;

传送门:$>here<$

题意

给出初始串FX,每分形一次所有X替换为X+YF,所有Y替换为FX-Y。问$n$代字符串第$p$位起长度为$l$的串。

数据范围:$n \leq 50, p \leq 10^9, l \leq 50$

Solution

将求解一个串转化为求解第$k$个字符。这样的话只有求解$l$次字符就好了。

如果直接暴力去做,肯定从初始串开始暴力去一轮一轮的展开。而实际上并不需要展开每一个,因为只需要求一个字符。我只需要知道它的位置就可以了。

问题的转化

我们考虑找出在每一轮中,我们所要求的字符包含于那个字符中——去展开那个我们需要的字符。而如何找出它包含于哪个字符这个问题只与展开后的长度有关。

问题转化为求解一个字符展开若干轮之后的长度。这是个子结构,可以用$(s,n)$来表示。通过观察我们发现,有递推关系$(s,n)=2(s,n-1)+2$

透过题解看本质

求第k大的问题

很多题目会让我求第$k$个答案。例如求第$k$字典序的字符串;有时并不是单单排序能解决的,例如求字典序第$k$大的LIS;也可能像这道题一样,询问一个庞大答案中的某一截。

联系学过的内容

在我们学过的内容中也有许多要求第$k$大的——最显然的就是主席树了。当然还有普通平衡树求解第$k$大。

这二者都是通过比较左子树与$k$的大小来决策第$k$大的位置。也就是说,将求第$k$大的问题转化为了判定问题。往往(类似于二分答案)转化为判定问题会简单很多。

通过暴力考虑优化

求解第$k$大的暴力做法是全部求出来然后取第$k$大。那么我们可以思考,前面那些是否对第$k$个有意义,是否可以省略。跳过我们不需要求的,就好像剪枝一样

my code

注意$l$的做的时候可能太大了会爆。刚好题目要我们求的位置不超过10亿,因此长度对10亿取min即可。

/*By DennyQi 2018*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 10010;
const int MAXM = 20010;
const int INF = 0x3f3f3f3f;
inline int Max(const int a, const int b){ return (a > b) ? a : b; }
inline int Min(const int a, const int b){ return (a < b) ? a : b; }
inline int read(){
    int x = 0; int w = 1; register char c = getchar();
    for(; c ^ ‘-‘ && (c < ‘0‘ || c > ‘9‘); c = getchar());
    if(c == ‘-‘) w = -1, c = getchar();
    for(; c >= ‘0‘ && c <= ‘9‘; c = getchar()) x = (x<<3) + (x<<1) + c - ‘0‘; return x * w;
}
int T,n,p,len,l[70];
inline char Char(int n, int k, bool c){
    if(n == 0){
        if(c == 0) return ‘X‘;
        else return ‘Y‘;
    }
    if(c == 0){
        if(l[n-1] >= k) return Char(n-1,k,0);
        if(l[n-1]+1 == k) return ‘+‘;
        if(l[n-1]+1+l[n-1] >= k) return Char(n-1,k-(l[n-1]+1),1);
        if(l[n-1]*2+2 == k) return ‘F‘;
    }
    else{
        if(k == 1) return ‘F‘;
        if(l[n-1]+1 >= k) return Char(n-1,k-1,0);
        if(l[n-1]+2 == k) return ‘-‘;
        if(l[n-1]*2+2 >= k) return Char(n-1,k-(l[n-1]+2),1);
    }
}
int main(){
    l[0] = 1;
    for(int i = 1; i <= 50; ++i) l[i] = Min((l[i-1]<<1) + 2, 1000000100);
    T = read();
    while(T--){
        n = read(), p = read(), len = read();
        for(int i = 0; i < len; ++i){
            if(p+i==1) printf("F");
            else printf("%c",Char(n,p+i-1,0));
        }
        puts("");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/qixingzhi/p/10349661.html

时间: 2024-08-02 22:40:15

「Algospot」龙曲线DRAGON的相关文章

「Algospot」QUANTIZE

第一道不难的DP例题,主要是为了总结这类题的思路:同时还学到了一个新操作 传送门:$>here<$ 题意 给出一个长度为$N$的序列,要求最多使用s个数字进行量化(有损压缩),即代替原数字:使得量化后各个被代替的数与代替的数的差的平方之和最小. 数据范围:$n \leq 100, s \leq 10$ Solution 动态规划的常规思路 容易发现肯定选择数值相近的一些数字用一个数字取替代,所以肯定先排序. 排序完后就是一个简单的dp题了.$dp[i][j]$表示前$i$个数字,使用$j$个数

「Algospot」津巴布韦ZIMBABWE

同时考验对状压DP和数位DP的理解: 传送门:$>here<$ 题意 给出一个数字$e$,现在对$e$通过$m$进行变换得到$x$:变换的要求是:1.只能改变原数字$e$各个数位的顺序(可以有前导零) 2.$x$是$m$的倍数 3. $x<e$ 问$x$有几种取值满足? 数据范围:$e \leq 10^14, m \leq 20$ Solution DFS怎么做是关键 这道题如果使用DFS,那么大体思路就是枚举每一位填放什么数字. 那么需要一个数组(状压)在此过程中来记录还可以用哪些数字

从「集装箱」思考Docker风潮

从「集装箱」思考Docker风潮 -- Docker潮流下的赢家策略 By 高焕堂 (台灣Docker聯盟 主席) 2015/02/20 前言 在许多革命性转折里,经常出现集装箱的身影:它就像幸运草一般,总是带来许多幸福和财运.现在Docker风起云涌,再现集装箱身影,如果开放视野.大力支持它,持续发挥它的潜能和力量,则幸运草就会出现在我们身旁了. 由于Docker集装箱带来的商机,其最直接的受益者是软件管理者(或称维运者),例如软件测试工具业者.测试人员等.因此在今天,不论您是开发者或是维运者

loj#2552. 「CTSC2018」假面

题目链接 loj#2552. 「CTSC2018」假面 题解 本题严谨的证明了我菜的本质 对于砍人的操作好做找龙哥就好了,blood很少,每次暴力维护一下 对于操作1 设\(a_i\)为第i个人存活的概率,\(d_i\)为死掉的概率,\(g_{i,j}\)是除i以外活了j个人的概率 那个选中i人的答案就是 \[a_i\times\sum_{j = 0} ^{k - 1}\frac{g_{i,j}}{j + 1}\] 对于\(g_{i,j}\) ,设\(f_{i,j}\)表示前\(i\)个人有\(

不设目标也能通关「马里奥」的AI算法,全靠好奇心学习

在强化学习中,设计密集.定义良好的外部奖励是很困难的,并且通常不可扩展.通常增加内部奖励可以作为对此限制的补偿,OpenAI.CMU 在本研究中更近一步,提出了完全靠内部奖励即好奇心来训练智能体的方法.在 54 个环境上的大规模实验结果表明:内在好奇心目标函数和手工设计的外在奖励高度一致:随机特征也能作为强大的基线. 通过与任务匹配的奖励函数最大化来训练智能体策略.对于智能体来说,奖励是外在的,并特定于它们定义的环境.只有奖励函数密集且定义良好时,多数的 RL 才得以成功实现,例如在电子游戏中的

程序员与新技术之间的「爱」与「恨」

我们大部分做技术的,对新技术是又爱又恨. 爱的是他能让枯燥反复的工作重新获得新鲜感. 恨的是新技术太多了,学不动啊. 真到了实际要运用的时候,不同人对待新技术的态度相差很大,有的看上去很积极,有的又看上去很排斥. 一般来说,技术团队的管理者往往是“排斥者”,而团队的成员是“拥抱者”的概率居多. 看看下面这个景象是不是很熟悉? 程序员小明:老大,XX系统太乱了,需要重构一下.我建议用XX技术,它的优点有XX.XX.XX.我开了一个分支,在项目中引入测试过了,没啥问题.重构应该要趁早,否则简直是煎熬

AC日记——「HNOI2017」单旋 LiBreOJ 2018

#2018. 「HNOI2017」单旋 思路: set+线段树: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define maxtree maxn<<2 int val[maxtree],tag[maxtree],L[maxtree],R[maxtree],mid[maxtree]; int op[maxn],ki[maxn],bi[maxn],cnt,size,n,ch[maxn]

「随笔」基于当下的思考

马德,说好的技术blog,变成日记本了... 下午的时候莫名其妙的感到很颓废,因为自己的不够强大感到忧虑和危机感十足.现在每每行走在技术的道路上,常觉得如履薄冰,如芒在背. 上大学之前和现在的心态其实差别挺大的,视野的开阔远远不止局限于自己的脚下.不过,这里的「上大学之前」只是一个时间描述词,并不觉得大学是最适合学习的地方,我很失望. 世界上的人无论性别,区域,宗教,兴趣爱好,总可以在互联网上找到志趣相同的人,总是可以不断打破自己的常识与惯性思维.总是有在相同领域比自己更强的人,挺好的. 关于知

「Unity」与iOS、Android平台的整合:3、导出的Android-Studio工程

本文属于「Unity与iOS.Android平台的整合」系列文章之一,转载请注明出处. Unity默认导出的是Android-Eclipse工程,毕竟Eclipse for Android开发在近一两年才开始没落,用户量还是非常巨大的. 个人认为AndroidStudio非常好用,能轻易解决很多Eclipse解决不了或者很难解决的问题. 所以我将Unity导出的Andoid工程分为Eclipse和AndroidStudio两部分. 不过我之后的相关内容都会使用AndroidStudio,希望依然