[CF1216E] Numerical Sequence hard version
题目
The only difference between the easy and the hard versions is the maximum value of k.
You are given an infinite sequence of form "112123123412345…" which consist of blocks of all consecutive positive integers written one after another. The first block consists of all numbers from 1 to 1, the second one — from 1 to 2, the third one — from 1 to 3, …, the i-th block consists of all numbers from 1 to i.
So the first 56 elements of the sequence are "11212312341234512345612345671234567812345678912345678910". Elements of the sequence are numbered from one. For example, the 1-st element of the sequence is 1, the 3-rd element of the sequence is 2, the 20-th element of the sequence is 5, the 38-th element is 2, the 56-th element of the sequence is 0.
Your task is to answer q independent queries. In the i-th query you are given one integer ki. Calculate the digit at the position ki of the sequence.
Input
The first line of the input contains one integer q (1≤q≤500) — the number of queries.
The i-th of the following q lines contains one integer ki (1≤ki≤1018) — the description of the corresponding query.
Output
Print q lines. In the i-th line print one digit xi (0≤xi≤9) — the answer to the query i, i.e. xi should be equal to the element at the position ki of the sequence.
Examples
Input
5
1
3
20
38
56
Output
1
2
5
2
0
Input
4
2132
506
999999999999999999
1000000000000000000
Output
8
2
4
1
Note
Answers on queries from the first example are described in the problem statement.
分析
我们维护一个前缀和数组,然后去找第n个数字在哪一行,然后减去前边几行的数字数目和就是答案。
比如n=5,发现它在第三行,前两行的和为3,5−3=2所以第五个数是2。 但如果n很大的话,比如这题,就会T掉,首先上述思想是可以肯定的,所以要用更高效的办法 首先是找到在第几行。 一行行枚举效率太低,要用到一个分块的思想,按照末位数字的位数分块,这样在每个块里找,枚举每个块的时间复杂度是一个常数,先找到它在哪一块,然后再利用二分的思想确定所在行,因为这个是具有单调性的,那么怎么找呢? 考虑每一块中有多少个数,用变量last记录前几个块的数字和,len记录当前枚举的位数,根据等差数列的求和公式(a1+an)∗n/2,当前块的第一行的数字和是last+len手摸一下就能得出,最后一行是last+len∗cnt,其中cnt就是该块内一共有多少数字,如果n大于前几块的数字和sum,就直接减去,否则就找到了所在块,然后再二分求出是那一行就行,求的方法就是不断更新l和r判断sum与n的关系,找到后再减去前边几行的和就是第n个数字在这一行第几个。 这时候我们再重复一下上述过程,只不过不是拆分行而是拆分每个数(不是数字),比如12345678910,拆成1 2 3 4 5 6 7 8 9 10,1和0不分开的这种。然后再枚举每个数字的位数,依次减去,从而求出第n个数字所在数的位数,最后再把这个数还原出来取它的那个位数就行。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int inf = 0x7f7f7f7f;
const int maxn = ;
int K,M,S,T;
int v[maxn],cnt,map[maxn][maxn],used[maxn];
int ans[maxn][maxn],dis[maxn][maxn],tmp[maxn][maxn];
void floyd(int c[][maxn],int a[][maxn],int b[maxn][maxn]){
int i,j,k;
for(k=;k<cnt;k++){
for(i=;i<cnt;i++){
for(j=;j<cnt;j++){
if(c[v[i]][v[j]]>a[v[i]][v[k]]+b[v[k]][v[j]])
c[v[i]][v[j]]=a[v[i]][v[k]]+b[v[k]][v[j]];
}
}
}
}
void copy(int a[][maxn],int b[][maxn]){
int i,j;
for(i=;i<cnt;i++){
for(j=;j<cnt;j++){
a[v[i]][v[j]]=b[v[i]][v[j]];
b[v[i]][v[j]]=inf;
}
}
}
void solve(int k){
while(k){
if(k%){
floyd(dis,ans,map);
copy(ans,dis);
}
floyd(tmp,map,map);
copy(map,tmp);
k=k/;
}
}
int main(){
int i,j;
int x,y,val;
while(scanf("%d%d%d%d",&K,&M,&S,&T)==){
for(i=;i<=;i++){
for(j=;j<=;j++){
map[i][j]=inf;
ans[i][j]=inf;
tmp[i][j]=inf;
dis[i][j]=inf;
}
ans[i][i]=;
}
memset(used,,sizeof(used));
cnt=;
for(i=;i<M;i++){
scanf("%d%d%d",&val,&x,&y);
if(map[x][y]>val){
map[x][y]=val;
map[y][x]=map[x][y];
}
if(!used[x]){
used[x]=;
v[cnt++]=x;
}
if(!used[y]){
used[y]=;
v[cnt++]=y;
}
}
solve(K);
printf("%d\n",ans[S][T]);
}
return ;
}
[CF1216E] Numerical Sequence hard version的更多相关文章
- Numerical Sequence (easy version)
http://codeforces.com/problemset/problem/1216/E1 E1. Numerical Sequence (easy version) time limit pe ...
- cf1216E2 Numerical Sequence (hard version)(思维)
cf1216E2 Numerical Sequence (hard version) 题目大意 一个无限长的数字序列,其组成为\(1 1 2 1 2 3 1.......1 2 ... n...\), ...
- cf1216E2 Numerical Sequence (hard version) 二分查找、思维题
题目描述 The only difference between the easy and the hard versions is the maximum value of k. You are g ...
- CF1216E Numerical Sequence
题目链接 问题分析 奇奇怪怪的题... 首先思路达成一致,从大到小一步一步确定位置. 我们一边分析,一边讲算法. 1121231234123451234561234567123456781234567 ...
- 【二分】CF Round #587 (Div. 3)E2 Numerical Sequence (hard version)
题目大意 有一个无限长的数字序列,其组成为1 1 2 1 2 3 1.......1 2 ... n...,即重复的1~1,1~2....1~n,给你一个\(k\),求第\(k(k<=10^{1 ...
- Numerical Sequence(hard version),两次二分
题目: 题意: 已知一个序列: 112123123412345123456123456712345678123456789123456789101234567891011... 求这个序列第k个数是多 ...
- Numerical Sequence (Hard vision) 题解
The only difference between the easy and the hard versions is the maximum value of \(k\). You are gi ...
- CF1264D2 Beautiful Bracket Sequence (hard version)
考虑\(D1\)的\(O(n^2)\),我们直接进行组合处理. 考虑在\(p\)这个位置,左边有\(l\)个(,右边有\(r\)个),左边有\(l\)个问号,右边有\(r\)个问号. 这个位置的贡献为 ...
- CF1264D1 Beautiful Bracket Sequence (easy version)
考虑在一个确定的括号序列中,我们可以枚举中间位置,按左右最长延伸出去的答案计算. 我们很自然的思考,我们直接维护左右两边,在删除一些字符后能够延伸的最长长度. 我们设\(f_{i,j}\)为\(i\) ...
随机推荐
- JavaSE(一) 语言概述
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 目录 1 基础常识 2 Java语言版本迭代概述 3 Java语言应用的领域 4 Java语言的特点 5 ...
- Java实现蓝桥杯模拟正整数序列的数量
问题描述 小明想知道,满足以下条件的正整数序列的数量: 1. 第一项为 n: 2. 第二项不超过 n: 3. 从第三项开始,每一项小于前两项的差的绝对值. 请计算,对于给定的 n,有多少种满足条件的序 ...
- Java实现第十届蓝桥杯旋转
试题 F: 旋转 时间限制: 1.0s 内存限制: 512.0MB 本题总分:15 分 [问题描述] 图片旋转是对图片最简单的处理方式之一,在本题中,你需要对图片顺时 针旋转 90 度. 我们用一个 ...
- 国外程序员整理的Java资源大全(全部是干货)
原文 译者 唐尤华 翻译自 github akullpp 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Ma ...
- 学习nginx从入门到实践(五) 场景实践之静态资源web服务
一.静态资源web服务 1.1 静态资源 静态资源定义:非服务器动态生成的文件. 1.2 静态资源服务场景-CDN 1.3 文件读取配置 1.3.1 sendfile 配置语法: syntax: se ...
- 解决Maven静态资源过滤问题
在项目的pom.xml中添加下面的内容 <build> <resources> <resource> <directory>src/main/java& ...
- STM32的ADC采样时间
STM32的ADC采样时间与其ADC的时钟频率密不可分. 例:STM32F103系列的ADC的时钟是在APB2(最大72MHZ)上.我们可以对其分频: RCC_PCLK2_Div2: ADC cloc ...
- MATLAB读取和保存nifti文件
介绍 分析核磁数据时,数据的读取和保存是两个基本的操作.虽然大部分工具包都对这些功能进行了封装,但是如果你不了解如何使用这些工具包或者说当前的任务太简单不值得去使用这些庞大的工具包的时候就需要我们自己 ...
- 2019-02-01 Python爬虫爬取豆瓣Top250
这几天学了一点爬虫后写了个爬取电影top250的代码,分别用requests库和urllib库,想看看自己能不能搞出个啥东西,虽然很简单但还是小开心. import requests import r ...
- iostst
原文链接:https://blog.csdn.net/qq_20332637/article/details/82146753 iostat用于输出CPU和磁盘I/O相关的统计信息,iostat 也有 ...