ls特别喜欢素数,他总是喜欢把素数集合的所有子集写下来,并按照一定的顺序和格式。对于每一个子集,集合内
的元素在写下来时是按照升序排序的,对于若干个集合,则以集合元素之和作为第一关键字,集合的字典序作为第
二关键字(先比较集合第一个元素,再比较第二个元素,以此类推),这个序列的开始如下:[2], [3], [2, 3], 
[5], [2, 5], [7], [3, 5], [2, 7], [2, 3, 5], [3, 7], [11], [2, 3, 7], [5, 7], [2, 11], [13], [2, 5, 
7]......注意:每个逗号的后面均有一个空格。现在ls想询问该序列位于区间[a,b]的子串是什么。
 

Input

输入仅一行包含两个数:a,b(1<=a<=b<=1e18,b-a<=100000)。
 

Output

输出序列中位于区间[a,b]的子串,前置或后置空格也应输出。
 

Sample Input

1 35

Sample Output

[2], [3], [2, 3], [5], [2, 5], [7],

题意:把素数集合按照和的大小排序,和相同的按照字典序排序,现在把这个排序后的序列看成一个字符串,问某个区间的字符串是什么。

思路:注意到素数不会太多,只有300来个,素数的和也不会太大,不会超过3000,所以我们递归去找即可。反正就是像数位DP那样搞就行了。。。

用记忆化递推缩小范围,然后用回溯暴力出ans。

#include<bits/stdc++.h>
#define ll long long
#define P pair<ll,ll>
using namespace std;
const int maxn=1e6;
int isprime[maxn],p[maxn];
vector<int>primes;
vector<int>vec;
map<P,P>M;
ll a,b,cur,prefix_len;
int getL(int x){
int res=;
while(x>){ res++; x/=;}
return res+;
}
inline P get(P p1,P p2,ll len){
return P(p1.first+p2.first,p1.second+p2.second+len*p1.first);
}
P calc(int x,int sum)
{
P p(x,sum);
if(sum<) return P(,);
if(M.count(p)) return M[p];
if(sum==) return M[p]=P(,); //ct,len
if(primes[x]>sum) return P(,);
return M[p]=get(calc(x+,sum-primes[x]),calc(x+,sum),getL(primes[x]));
}
void ptchar(char c){
cur++; if(cur>=a&&cur<=b) putchar(c);
}
void print(int x){
vector<int>v;
while(x>){ v.push_back(x%); x/=;}
for(int i=v.size()-;i>=;i--) ptchar(char(v[i]+''));
}
void print(int x,int sum)
{
if(sum<||cur>=b) return ;
if(sum==){
ptchar('[');
for(int i=;i<vec.size();i++){
print(vec[i]);
if(i==vec.size()-) ptchar(']');
ptchar(',');
ptchar(' ');
} return ;
}
if(primes[x]>sum) return ;
vec.push_back(primes[x]);
prefix_len+=getL(primes[x]);
ll len=prefix_len*calc(x+,sum-primes[x]).first+calc(x+,sum-primes[x]).second;
if(len+cur>=a) print(x+,sum-primes[x]);
else cur+=len; vec.pop_back();
prefix_len-=getL(primes[x]);
len=prefix_len*calc(x+,sum).first+calc(x+,sum).second;
if(len+cur>=a) print(x+,sum);
else cur+=len;
}
int main()
{
freopen("list.in","r",stdin);
freopen("list.out","w",stdout);
isprime[]=false;
fill(isprime,isprime+maxn,true);
for(int i=;i<maxn;i++){
if(isprime[i]){
primes.push_back(i);
for(int j=i+i;j<maxn;j+=i) isprime[j]=false;
}
}
scanf("%I64d%I64d",&a,&b);
for(int i=;i<&&cur<b;i++){ //试探过,i最大到2096,这个范围的素数也就300来个,所以记忆化
ll len=calc(,i).second;
if(cur+len>=a) print(,i);
else cur+=len;
}
puts("");
return ;
}

Codeforces Gym 101190 NEERC 16 .L List of Primes(递归)的更多相关文章

  1. Codeforces Gym 101190 NEERC 16 G. Game on Graph(博弈+拓扑)

    Gennady and Georgiy are playing interesting game on a directed graph. The graph has n vertices and m ...

  2. Codeforces Gym 101190 NEERC 16 .D Delight for a Cat (上下界的费用流)

    ls是一个特别堕落的小朋友,对于n个连续的小时,他将要么睡觉要么打隔膜,一个小时内他不能既睡觉也打隔膜 ,因此一个小时内他只能选择睡觉或者打隔膜,当然他也必须选择睡觉或打隔膜,对于每一个小时,他选择睡 ...

  3. 【Codeforces Gym 100725K】Key Insertion

    Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...

  4. Codeforces gym 101343 J.Husam and the Broken Present 2【状压dp】

     2017 JUST Programming Contest 2.0 题目链接:Codeforces gym 101343 J.Husam and the Broken Present 2 J. Hu ...

  5. codeforces gym 100553I

    codeforces gym 100553I solution 令a[i]表示位置i的船的编号 研究可以发现,应是从中间开始,往两边跳.... 于是就是一个点往两边的最长下降子序列之和减一 魔改树状数 ...

  6. Codeforces Gym 101252D&&floyd判圈算法学习笔记

    一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...

  7. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

  8. Codeforces Gym 101623A - 动态规划

    题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...

  9. CodeForces Gym 100213F Counterfeit Money

    CodeForces Gym题目页面传送门 有\(1\)个\(n1\times m1\)的字符矩阵\(a\)和\(1\)个\(n2\times m2\)的字符矩阵\(b\),求\(a,b\)的最大公共 ...

随机推荐

  1. VueJS绑定缩写:可省略v-on、v-bind

    v-bind 缩写 Vue.js 为两个最为常用的指令提供了特别的缩写: <!-- 完整语法 --> <a v-bind:href="url"></a ...

  2. View的滚动原理简单解析

    一直对View的滚动了解的不深,说明确了吧也能说出个所以然来,所以我就花了点时间做了一个小小的总结,言归正传,view的滑动分为下面三种: 1)View本身不滚动,指滚动View的内容,这也是View ...

  3. QTreeWidget 的用法

    Qt QTreeWidget 新建一个Qt Widgets Application,拖拽一个Tree Widget 到 ui 界面上,最后实现的效果如下: 添加代码 //test.h //在头文件里添 ...

  4. Selenium学习(三)Selenium总是崩溃的解决办法

    在使用selenium打开浏览器总是崩溃,最近查资料获得可行的解决办法: import sys from selenium import webdriver p = __import__('selen ...

  5. 彻底隐藏Nginx版本号的安全性与方法

    Nginx默认是显示版本号的,如: [root@bkjz ~]# curl -I www.nginx.orgHTTP/1.1 200 OKServer: nginx/0.8.44Date: Tue, ...

  6. FloatingActionButton 完全解析

    鸿洋大神说的很明白这里就直接引用一下: FloatingActionButton 完全解析[Design Support Library(2)]

  7. UVALive 6530 Football (水

    题目链接:点击打开链 #include <cstdio> #include <vector> #include <algorithm> using namespac ...

  8. Tensorflow教程

    中文社区 tensorflow笔记:流程,概念和简单代码注释 TensorFlow入门教程集合 tensorboard教程:2017 TensorFlow 开发者峰会 TensorBoard轻松实践  ...

  9. EasyNVR流媒体服务器接入EasyDSS云视频平台快照上传实现

    EasyNVR拥有接入EasyDSS云平台的功能 接入EasyDSS云平台会定时向云平台上传快照数据,这个快照数据用于云平台向客户端提供快照展示 遇到的问题 由于快照上传的间隔提供认为修改的功能,则我 ...

  10. Notepad工具使用小技巧

    工欲善其事必先利其器 Notepad++是个很不错的文本编辑工具,掌握它的使用技巧可以提高我们工作的效率.见如下: 比较常用的罗列如下:(如果有更好的建议可以留言哈) 1: 添加书签 CTRL+F2 ...