题面

我先对数字根打了个表,然后得到了一个结论:\(a\)的数字根=\((a-1)mod 9+1\)

我在询问大佬后,大佬给出了一个简单的证明:

\(\because 10^n\equiv 1(mod 9)\)

\(\therefore a_{n}*10^n+a_{n-1}*10^{n-1}+...+a_{1}\equiv a_{n}+a_{n-1}+...+a_{1}(mod 9)\)

这样的话一个区间\([l,r]\)的数字根就可以转化为\((pre_{r}-pre_{l-1}-1)mod 9+1\),\(pre_{i}\)表示前缀和。

考虑预处理出一个数组\(last_{i,j}\)表示右端点为\(i\)数字根为\(j\)的区间的左端点的\(max\)。

但是这样的话按原式子做感觉很麻烦。

所以再把这个式子拆一下得:\((pre_{r}-pre_{l-1}-1)mod 9+1=((pre_{r}-1)mod 9-pre_{l-1}mod 9+9)mod 9+1\)

这样就好搞多了。

那处理出来这个\(last\)有什么用呢...

考虑如果查询一个区间内是否存在一个子区间的数字根为\(j\)的话,我们只要查询\(max(last_{i,j})<=l(i\in[l,r])\)就行了。

那么只要求个区间max是否\(<=l\)就行了,\(st\),线段树随便上吧。

网上另外两篇题解都是暴力是smg,\(10^5\)个\(0\)随便卡啊

#include<bits/stdc++.h>
#define For(i,x,y) for (register int i=(x);i<=(y);i++)
#define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
#define cross(i,u) for (register int i=first[u];i;i=last[i])
using namespace std;
typedef long long ll;
inline ll read(){
ll x=0;int ch=getchar(),f=1;
while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
if (ch=='-'){f=-1;ch=getchar();}
while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int N = 1e5+10;
int n,a[N];
ll pre[N];
inline void rd(){
n=read();
For(i,1,n) a[i]=read(),pre[i]=pre[i-1]+a[i];
}
int Log[N],last[N][10],now[10],p[20],Max[N][20][10];
inline void init(){
For(i,1,8) now[i]=-1;
For(i,1,n){
if (!a[i]){For(j,1,9) last[i][j]=last[i-1][j];last[i][0]=i-1;}
else{For(j,0,8) last[i][((pre[i]-1)%9-j+9)%9+1]=now[j];last[i][0]=-1;}
now[pre[i]%9]=i;
//For(j,1,9) printf("%d ",last[i][j]);puts("");
}
For(i,1,n) Log[i]=log2(i);
p[0]=1;
For(i,1,Log[n]) p[i]=p[i-1]<<1;
For(i,1,n)
For(j,0,9) Max[i][0][j]=last[i][j];
For(j,1,Log[n])
For(i,1,n-p[j]+1)
For(k,0,9) Max[i][j][k]=max(Max[i][j-1][k],Max[i+p[j-1]][j-1][k]);
}
inline int query(int l,int r,int k){
int L=Log[r-l+1];
return max(Max[l][L][k],Max[r-p[L]+1][L][k]);
}
int q,l,r,cnt;
inline void work(){
q=read();
while (q--){
l=read(),r=read(),cnt=0;
Dow(i,9,0)
if (query(l,r,i)+1>=l){
printf("%d ",i),cnt++;
if (cnt==5) break;
}
For(i,cnt+1,5) printf("-1 ");puts("");
}
}
int main(){
rd(),init(),work();
}

Luogu P3962 [TJOI2013]数字根 st的更多相关文章

  1. 洛谷 P3962 [TJOI2013]数字根 解题报告

    P3962 [TJOI2013]数字根 题意 数字根:这个数字每一位的数字加起来求和,反复这个过程直到和小于10. 给出序列\(a\),询问区间\([l,r]\)连续的子区间里最大前5个不同的数字根, ...

  2. TJOI2013数字根

    题面链接 洛谷 sol 我们先不考虑\(0\),发现数字根\(=\)它\(mod 9\). 我们前缀和一波,把区间和变成两数相减. 对于每个\(v\in\{0-8\}\),(这里面的\(mod 9=0 ...

  3. 洛谷3962 [TJOI2013]数字根

    题目描述 一个数字的数字根定义为:这个数字每一位的数字加起来求和,反复这个过程直到和小于10.例如,64357的数字跟为7,因为6+4+3+5+7=25,2+5=7个区间的数字根定义为这个区间所有数字 ...

  4. 数字根(digital root)

    来源:LeetCode 258  Add Dights Question:Given a non-negative integer  num , repeatedly add all its digi ...

  5. 1. 数字根(Digital Root)

    数字根(Digital Root)就是把一个自然数的各位数字相加,再将所得数的各位数字相加,直到所得数为一位数字为止.而这个一位数便是原来数字的数字根.例如: 198的数字根为9(1+9+8=18,1 ...

  6. ACM之数论数字根

    先来看一道杭电的数字根问题 此题的大大意是输入一个数.假设它不是一位的数字的话,那么我们就将它的每一位都相加,相加后假设还是两位或者很多其它的话那么我们继续取出它的每一位数字进行相加.知道等到单个数字 ...

  7. 51nod——1174 区间中最大的数(ST)

    题目链接 给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,最大的数是多少. 例如: 1 7 6 3 1.i = 1, j = 3,对应的数为7 6 3,最大的数 ...

  8. BZOJ 3930 Luogu P3172 选数 (莫比乌斯反演)

    手动博客搬家:本文发表于20180310 11:46:11, 原地址https://blog.csdn.net/suncongbo/article/details/79506484 题目链接: (Lu ...

  9. luogu P5023 填数游戏

    luogu loj 被这道题送退役了 题是挺有趣的,然而可能讨论比较麻烦,肝了2h 又自闭了,鉴于CSP在即,就只能先写个打表题解了 下面令\(n<m\),首先\(n=1\)时答案为\(2^m\ ...

随机推荐

  1. python学习笔记(十三)之lambda表达式

    lambda表达式: 用法 lambda x : 2 * x + 1 其中:前面是参数,后面是返回值. >>> def ds(x): ... return 2 * x + 1 ... ...

  2. C语言实现线性表(链式存储方式)

    #include <stdio.h> #include <stdlib.h> //提供malloc()原型 typedef struct LNode *List; typede ...

  3. Price(洛谷P4109 [HEOI2015]定价)

    题目 思路: 按照我的思路这一题应该是这样子的 剔除+判断 剔除 因为后面的0要越多越好,所以我们判断0出现的情况,当2个数之间的差大与10时,证明2个之间会存在一个0,所以这一位我们可以把它去掉,相 ...

  4. localStorage H5本地存储

    域内安全.永久保存.即客户端或浏览器中来自同一域名的所有页面都可访问localStorage数据且数据除了删除否则永久保存,但客户端或浏览器之间的数据相互独立. <!doctype html&g ...

  5. 学习Python函数笔记之二(内置函数)

    ---恢复内容开始--- 1.内置函数:取绝对值函数abs() 2.内置函数:取最大值max(),取最小值min() 3.内置函数:len()是获取序列的长度 4.内置函数:divmod(x,y),返 ...

  6. JSON.parse()——json字符串转JS

    JSON 通常用于与服务端交换数据. 在接收服务器数据时一般是字符串. 我们可以使用 JSON.parse() 方法将数据转换为 JavaScript 对象. 语法 JSON.parse(text[, ...

  7. python基础===对字符串进行左右中对齐

    例如,有一个字典如下: >>> dic = { "name": "botoo", "url": "http:// ...

  8. [转载]hazard pointer

    hazard pointer 转载自: http://hi.baidu.com/rodimus/item/f6539cc179894f2f47d5c0ef 这是用于解决多线程并发下内存的回收,一块内存 ...

  9. 父元素的mousedown事件上父元素的mousedown事件上的offsetX和offsetY错误的offsetX和offsetY错误

    https://stackoverflow.com/questions/35360704/wrong-offsetx-and-offsety-on-mousedown-event-of-parent- ...

  10. prototype 与 __proto__

    原文:http://rockyuse.iteye.com/blog/1426510 说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: 1 <script type= ...