Problem

Description

小 B 有一个很大的数 \(S\),长度达到了 \(N\) 位;这个数可以看成是一个串,它可能有前导 \(0\),例如 00009312345 。小 B 还有一个素数 \(P\)。

现在,小 B 提出了 \(M\) 个询问,每个询问求 \(S\) 的一个子串中有多少子串是 \(P\) 的倍数(\(0\) 也是 \(P\) 的倍数)。例如 \(S\) 为 0077 时,其子串 007 有六个子串:0, 0, 7, 00, 07, 007;显然 0077 的子串 077 的六个子串都是素数 \(7\) 的倍数。

Input Format

第一行一个整数:\(P\)。

第二行一个串:\(S\)。

第三行一个整数:\(M\)。

接下来 \(M\) 行,每行两个整数 \(\text{fr}, \text{to}\),表示对 \(S\) 的子串 \(S[\text{fr} \ldots \text {to}]\) 的一次询问。

注意:\(S\) 的最左端的数字的位置序号为 \(1\);例如 \(S\) 为 \(213567\),则 \(S[1]\) 为 \(2\),\(S[1 \ldots 3]\)为 \(213\)。

Output Format

输出 \(M\) 行,每行一个整数,第 \(i\) 行是第 \(i\) 个询问的答案。

Sample

Input

11
121121
3
1 6
1 5
1 4

Output

5
3
2

Explanation

Explanation for Input

第一个询问问的是整个串,满足条件的子串分别有:121121211211121121

Range

对于所有的数据,\(N,M \leq 100000\),\(P\) 为素数。

Algorithm

莫队

Mentality

嗯 \(......\) 比较送分的题目。

支持 \(nlog\) 的数据范围,可离线的区间询问,且问的内容一看就可以莫队 = = 。

我们发现,设 \(r[i]\) 为 \([i,n]\) 组成的数,那么有:

\[num(i,j)=\frac{(r[i]-r[j+1])}{10^{n-j}}
\]

我们把分母移到左边去,那么便有:

\[num(i,j)\cdot 10^{n-j}=r[i]-r[j+1]\\
num(i,j)\cdot 10^{n-j}\ mod\ P=(r[i]-r[j+1])\ mod\ P \\
num(i,j)\cdot 10^{n-j}\ mod\ P=r[i]\ mod\ P-r[j+1]\ mod\ P
\]

那么,当 \(r[i]\) 与 \(r[j+1]\) 对 \(P\) 取模的余数相同,那等式就必定等于 \(0\) ,则有:

\[num(i,j)\cdot 10^{n-j}\ mod\ P=0
\]

那么当 \(10^{n-j}\ mod\ P\neq 0\) 时,因为最后的结果为 \(0\) ,所以必有 \(num(i,j)\ mod\ P=0\) 。

也就是说,当 \(P\neq 2,5\) 时,\(num(i,j)\) 为 \(P\) 的倍数当且仅当 \(r[i]\) 和 \(r[j+1]\) 关于模数 \(P\) 同余。

那么我们的问题就变成了一个区间内有多少属性相同的点对了,这个就很莫队了。

至于 \(P=2,5\) 的时候,特判处理即可。我们可以直接通过判断一个数的末位来判断这个数是否为 \(P\) 的倍数,我们可以直接记前缀和哇。

Code

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n, m, mod, size, rest[100002], L, R, cnt, now[100001], ano[10][100001],
sum[100001];
char S[100001];
long long ans, answer[100001], q[100001];
struct Que {
int l, r, q, d;
} k[100001];
struct node {
int d, rest;
} ls[100002];
bool cmp(Que a, Que b) { return a.q == b.q ? a.r < b.r : a.q < b.q; }
bool cmp2(node a, node b) { return a.rest < b.rest; }
void Del(int x) { ans -= --now[rest[x]]; }
void Add(int x) { ans += now[rest[x]]++; }
int main() {
cin >> mod >> S >> m;
n = strlen(S);
size = sqrt(n);
for (int i = 1; i <= m; i++) {
scanf("%d%d", &k[i].l, &k[i].r);
k[i].q = k[i].l / size;
k[i].r++;
k[i].d = i;
}
if (mod == 2 || mod == 5) {
for (int i = n; i > 0; i--) {
sum[i] = sum[i + 1];
if ((S[i - 1] - '0') % mod == 0) sum[i]++;
} //记录后缀中有多少个数是合法末位
for (int i = n; i > 0; i--)
q[i] =
sum[i] + q[i + 1]; //记录后缀的后缀和,也就是后缀中有多少合法的区间
for (int i = 1; i <= m; i++)
printf(
"%lld\n",
q[k[i].l] - q[k[i].r] -
(k[i].r - k[i].l) *
sum[k[i].r]); //计算答案:区间的后缀和相减,再减去区间之外的末位对区间的贡献
return 0;
}
sort(k + 1, k + m + 1, cmp);
for (int i = 1; i <= 9; i++) {
ano[i][1] = i % mod;
for (int j = 2; j <= n; j++)
ano[i][j] =
1ll * ano[i][j - 1] * 10 % mod; //计算每个数作为第 j 位时在 %P 下的值
}
for (int i = n; i >= 1; i--) {
ls[i].rest = (ls[i + 1].rest + ano[S[i - 1] - '0'][n - i + 1]) %
mod; //记录每个 r[i] 的 %P 之后的值
ls[i].d = i;
}
sort(ls + 1, ls + n + 1, cmp2);
for (int i = 1; i <= n; i++) {
if (ls[i].rest > ls[i - 1].rest) cnt++;
rest[ls[i].d] = cnt;
} //将余数离散化才能存
L = k[1].l, R = k[1].l - 1;
for (int i = 1; i <= m; i++) {
while (L < k[i].l) Del(L++);
while (L > k[i].l) Add(--L);
while (R < k[i].r) Add(++R);
while (R > k[i].r) Del(R--);
answer[k[i].d] = ans;
}
for (int i = 1; i <= m; i++) printf("%lld\n", answer[i]);
}

【HNOI 2016】大数的更多相关文章

  1. [HNOI 2016]大数

    Description 题库链接 给你一个长度为 \(n\) ,可含前导零的大数,以及一个质数 \(p\) . \(m\) 次询问,每次询问你一个大数的子区间 \([l,r]\) ,求出子区间中有多少 ...

  2. [HNOI 2016]树

    Description 题库链接 给你一棵 \(N\) 个节点根节点为 \(1\) 的有根树,结点的编号为 \(1\sim N\) :我们称这颗树为模板树.需要通过这棵模板树来构建一颗大树.构建过程如 ...

  3. 【BZOJ 4539】【HNOI 2016】树

    http://www.lydsy.com/JudgeOnline/problem.php?id=4539 今天测试唯一会做的一道题. 按题目要求,如果暴力的把模板树往大树上仍,最后得到的大树是$O(n ...

  4. hnoi 2016 省选总结

    感觉省选好难的说...反正我数据结构太垃圾正解想到了也打不出来打一打暴力就滚粗了! DAY1 0+20+30 DAY2 60-20+0+60 最后170-20分,暴力分还是没有拿全! 然而这次是给了5 ...

  5. HNOI 2016 省队集训日记

    第一天 DeepDarkFantasy 从东京出发,不久便到一处驿站,写道:日暮里.  ——鲁迅<藤野先生> 定义一个置换的平方为对1~n的序列做两次该置换得到的序列.已知一个置换的平方, ...

  6. 数据结构(树链剖分,堆):HNOI 2016 network

    2215. [HNOI2016]网络 ★★★☆   输入文件:network_tenderRun.in   输出文件:network_tenderRun.out   简单对比时间限制:2 s   内存 ...

  7. [HNOI 2016]最小公倍数

    Description 题库链接 给定一张 \(N\) 个顶点 \(M\) 条边的无向图(顶点编号为 \(1,2,\cdots,n\) ),每条边上带有权值.所有权值都可以分解成 \(2^a\time ...

  8. [HNOI 2016]序列

    Description 题库链接 给你一个长度为 \(n\) 的序列 \(A\) ,给出 \(q\) 组询问.每次询问 \([l,r]\) ,求该区间内所有的子序列中最小值的和. \(1\leq n, ...

  9. [HNOI 2016]网络

    Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做 一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有 ...

随机推荐

  1. Spring Boot Thmeleaf的语法 day04

    一.Thmeleaf语法的使用 html格式的页面放在classpath:/templates/就会自动渲染. 1.在pom.xml导入 <dependency> <groupId& ...

  2. href和src的区别(小计)

    1.Src 是指向物件的来源地址,请求src资源时会将其指向的资源下载并应用文档中 src的内容是页面上比不可少的一部分,是引入.在 img.script.iframe 等元素上使用. 2.href ...

  3. #WEB安全基础 : HTTP协议 | 0x15 HTTPS:给你点颜色看看

    "你好,我是HTTPS,我只是披了个外壳,我还是原来的HTTP." 这是HTTPS叫我转达给你的话. HTTPS本质上就是HTTP,只不过加了点调料.它比HTTP更安全,使用了加密 ...

  4. 安装rlwrap-0.37.tar.gz

    1.解压下载好的rlwrap文件 [root@wangliping tool]# tar -zxvf rlwrap-0.37.tar.gz 2.进入解压好的文件[root@wangliping too ...

  5. 再谈HTTP2性能提升之背后原理—HTTP2历史解剖

    即使千辛万苦,还是把网站升级到http2了,遇坑如<phpcms v9站http升级到https加http2遇到到坑>. 因为理论相比于 HTTP 1.x ,在同时兼容 HTTP/1.1 ...

  6. 阿里云新老用户购买 2核8G云服务器5M带宽

    这次阿里云活动的力度还是很大的,2核8G云服务器5M带宽 3年才2070 ,还是很值的购买的. 也放一个我的团战队连接,欢迎大家一起拼低价 https://m.aliyun.com/act/team1 ...

  7. 求方差分析与两样本T检验 区别

    方差分析与两样本T检验. 1.首先可以看到方差分析(ANOVA)包含两样本T检验,把两样本T检验作为自己的特例.因为ANOVA可以比较多个总体的均值,当然包含两个总体作为特例.实际上,T的平方就是F统 ...

  8. week1 - Python基础1 介绍、基本语法、流程控制

    知识内容: 1.python介绍 2.变量及输入输出 3.分支结构 4.循环结构 一.python介绍 Python主要应用领域: 云计算: 云计算最火的语言, 典型应用OpenStack WEB开发 ...

  9. vuejs简单介绍特点

    官网:https://cn.vuejs.org/ vue是一个渐进式的框架, 是一个轻量级的框架, 也不算是一个框架, 他核心只关注图层, 是一个构建数据驱动的web界面,易于上手, 还便于于第三方库 ...

  10. python locust 性能测试:HttpSession

    官网解释:用于在请求之间执行Web请求和保留(会话)cookie的类(以便能够登录和退出网站):记录每个请求,以便locust可以显示统计信息: from locust import TaskSet, ...