[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\) ...
随机推荐
- Java 解析 XML文件
个人博客网:https://wushaopei.github.io/ (你想要这里多有) package com.example.poiutis.xml; import com.example ...
- Java实现 LeetCode 797 所有可能的路径 (DFS)
797. 所有可能的路径 给一个有 n 个结点的有向无环图,找到所有从 0 到 n-1 的路径并输出(不要求按顺序) 二维数组的第 i 个数组中的单元都表示有向图中 i 号结点所能到达的下一些结点(译 ...
- Java实现 蓝桥杯 算法提高 GPA(暴力)
试题 算法提高 GPA 问题描述 输入A,B两人的学分获取情况,输出两人GPA之差. 输入格式 输入的第一行包含一个整数n表示A的课程数,以下n行每行Si,Ci分别表示第i个课程的学分与A的表现. G ...
- ASP.NET通过EntityFramework CodeFirst创建数据库
Number1 新建一个项目 给新项目添加一个实体数据模型 选择第三个 这里我创建两个有关系的类,也就是有外键关系的数据库表 using System; using System.Collection ...
- Java实现 LeetCode 257 二叉树的所有路径
257. 二叉树的所有路径 给定一个二叉树,返回所有从根节点到叶子节点的路径. 说明: 叶子节点是指没有子节点的节点. 示例: 输入: 1 / \ 2 3 \ 5 输出: ["1->2 ...
- Java实现 蓝桥杯VIP 算法提高 前10名
算法提高 前10名 时间限制:1.0s 内存限制:256.0MB 问题描述 数据很多,但我们经常只取前几名,比如奥运只取前3名.现在我们有n个数据,请按从大到小的顺序,输出前10个名数据. 输入格式 ...
- java实现拉丁方块填数字
"数独"是当下炙手可热的智力游戏.一般认为它的起源是"拉丁方块",是大数学家欧拉于1783年发明的. 如图[1.jpg]所示:6x6的小格被分为6个部分(图中用 ...
- java实现第七届蓝桥杯剪邮票
剪邮票 题目描述 如[图1.jpg], 有12张连在一起的12生肖的邮票. 现在你要从中剪下5张来,要求必须是连着的. (仅仅连接一个角不算相连) 比如,[图2.jpg],[图3.jpg]中,粉红色所 ...
- Php-webdriver 的安装与使用教程
Php-webdriver 是 Facebook 开发的基于 PHP 语言实现的 Selenium WebDriver 客户端组件,可以用它来操作浏览器.常见的操作包括:自动化测试.采集数据等. 安装 ...
- 分布式数据库PolonDB 云端发力未来数据处理需求
企业数字化转型的不断深入,传统 IT 架构和数据库早已无法适应诸如物联网.新金融.新零售.新制造等行业对于数据高吞吐.灵活扩展等需求,企业对数据库有了更高的要求. 青云QingCloud 本次推出的 ...