题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=4542

题解

我们令 \(f_i\) 表示从 \(i\) 到 \(n\) 位组成的数 \(\bmod P\) 的值。

那么一个从 \(l, r\) 的串的权值为 \(\frac{f_l - f_{r+1}}{10^{n-r}}\)。

如果需要这个东西 \(=0\),也就是

\[\frac{f_l - f_{r+1}}{10^{n-r}} = 0 \pmod P
\]

下一步显然是要把 \(10^{n-r}\) 乘上去。但是 \(10^{n-r}\) 在模 \(P\) 意义下有逆元,当且仅当 \(10\) 和 \(P\) 互质。

所以要分成两种情况。


第一种是 \(P=2\) 或者 \(5\),此时 \(10\) 和 \(P\) 不互质,不能直接乘 \(10^{n-r}\)。

但是可以发现,\(P=2\) 时,满足条件的子串末尾一定是 \(2, 4, 6, 8, 0\);\(P=5\) 时,满足条件的子串末尾一定是 \(5, 0\)。

可以直接使用这个性质解决。


第二种就是 \(P \neq 2, 5\)。此时 \(10\) 和 \(P\) 互质,所以我们把 \(10^{n-r}\) 乘过去。

得到 \(f_l - f_{r+1} = 0\)。

也就是说对于一次询问 \(l, r\) 我们需要做的就是找到 \([l, r+1]\) 这个区间内的权值相同的点对的个数。

可以使用莫队解决。


最坏情况下时间复杂度 \(O(m\sqrt n)\)。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 100000 + 7; #define bl(x) (((x) - 1) / blo + 1) int n, m, P;
char a[N]; namespace Task1 {
inline bool istask() { return P == 2 || P == 5; }
int s[N];
ll ss[N]; inline void work() {
for (int i = 1; i <= n; ++i) a[i] -= '0';
for (int i = 1; i <= n; ++i) s[i] = s[i - 1] + !(a[i] % P), ss[i] = ss[i - 1] + i * !(a[i] % P); read(m);
while (m--) {
int l, r;
read(l), read(r);
printf("%lld\n", ss[r] - ss[l - 1] - (l - 1ll) * (s[r] - s[l - 1]));
}
}
} namespace Task2 {
int dis, blo;
ll msum = 0;
int f[N], b[N], cnt[N];
ll ans[N];
struct Query {
int l, r;
ll *ans;
inline bool operator < (const Query &b) { return bl(l) != bl(b.l) ? l < b.l : r < b.r; }
} q[N]; inline int smod(int x) { return x >= P ? x - P : x; }
inline void sadd(int &x, const int &y) { x += y; x >= P ? x -= P : x; }
inline int fpow(int x, int y) {
int ans = 1;
for (; y; y >>= 1, x = (ll)x * x % P) if (y & 1) ans = (ll)ans * x % P;
return ans;
} inline void madd(int x) {
int &v = f[x];
msum -= (ll)cnt[v] * (cnt[v] - 1) / 2;
++cnt[v];
msum += (ll)cnt[v] * (cnt[v] - 1) / 2;
}
inline void mdel(int x) {
int &v = f[x];
assert(cnt[v]);
msum -= (ll)cnt[v] * (cnt[v] - 1) / 2;
--cnt[v];
msum += (ll)cnt[v] * (cnt[v] - 1) / 2;
} inline void ycl() {
int ten = 1;
for (int i = 1; i <= n; ++i) a[i] -= '0';
for (int i = n; i; --i) f[i] = smod(f[i + 1] + (ll)a[i] * ten % P), ten = 10ll * ten % P;
memcpy(b + 1, f + 1, sizeof(int) * (n + 1));
}
inline void lsh() {
std::sort(b + 1, b + n + 1);
dis = std::unique(b + 1, b + n + 1) - b - 1;
for (int i = 1; i <= n; ++i) f[i] = std::lower_bound(b + 1, b + dis + 1, f[i]) - b;
} inline void work() {
blo = sqrt(n);
ycl();
++n;
lsh();
read(m);
for (int i = 1; i <= m; ++i) read(q[i].l), read(q[i].r), ++q[i].r, q[i].ans = ans + i;
std::sort(q + 1, q + m + 1);
int l = 1, r = 0;
for (int i = 1; i <= m; ++i) {
while (l > q[i].l) madd(--l);
while (r < q[i].r) madd(++r);
while (l < q[i].l) mdel(l++);
while (r > q[i].r) mdel(r--);
*q[i].ans = msum;
}
for (int i = 1; i <= m; ++i) printf("%lld\n", ans[i]);
}
} inline void init() {
read(P);
scanf("%s", a + 1);
n = strlen(a + 1);
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
if (Task1::istask()) Task1::work();
else Task2::work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj4542 [Hnoi2016]大数 莫队+同余的更多相关文章

  1. [BZOJ4542] [Hnoi2016] 大数 (莫队)

    Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个 ...

  2. 【BZOJ4542】[Hnoi2016]大数 莫队

    [BZOJ4542][Hnoi2016]大数 Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个 ...

  3. 【bzoj4542】[Hnoi2016]大数 莫队算法

    题目描述 给出一个数字串,多次询问一段区间有多少个子区间对应的数为P的倍数.其中P为质数. 输入 第一行一个整数:P.第二行一个串:S.第三行一个整数:M.接下来M行,每行两个整数 fr,to,表示对 ...

  4. BZOJ.4542.[HNOI2016]大数(莫队)

    题目链接 大数除法是很麻烦的,考虑能不能将其条件化简 一段区间[l,r]|p,即num[l,r]|p,类似前缀,记后缀suf[i]表示[i,n]的这段区间代表的数字 于是有 suf[l]-suf[r+ ...

  5. 洛谷P3245 [HNOI2016]大数(莫队)

    题意 题目链接 Sol 莫队板子题.. 维护出每个位置开始的字符串\(mod P\)的结果,记为\(S_i\) 两个位置\(l, r\)满足条件当且仅当\(S_l - S_r = 0\),也就是\(S ...

  6. [BZOJ4542] [JZYZOJ2014][Hnoi2016] 大数(莫队+离散化)

    正经题解在最下面 http://blog.csdn.net/qq_32739495/article/details/51286548 写的时候看了大神的题解[就是上面那个网址],看到下面这段话 观察题 ...

  7. bzoj 4542: [Hnoi2016]大数 (莫队)

    Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个 ...

  8. [HNOI2016]序列(莫队,RMQ)

    [HNOI2016]序列(莫队,RMQ) 洛谷  bzoj 一眼看不出来怎么用数据结构维护 然后还没修改 所以考虑莫队 以$(l,r-1) -> (l,r)$为例 对答案的贡献是$\Sigma_ ...

  9. 【莫队】bzoj4542: [Hnoi2016]大数

    挺有意思的,可以仔细体味一下的题:看白了就是莫队板子. Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小 ...

随机推荐

  1. 自动化运维--ansible(1)

    前戏 ansible 批量在远程主机上执行命令 openpyxl 操作excel表格 puppet ansible slatstack ansible epel源 第一步: 下载epel源 wget ...

  2. STL标准库-容器-set与map

    STL标准库-容器-set与multiset C++的set https://www.cnblogs.com/LearningTheLoad/p/7456024.html STL标准库-容器-map和 ...

  3. excel 字母变大写 宏

    Sub ConvertToUpperCase() Dim Rng As Range Worksheets("Sheet1").UsedRange.Select For Each R ...

  4. JS获取URL中参数值

    一.正则法: function getQueryString(name) { var reg = new RegExp('(^|&)' + name + '=([^&]*)(& ...

  5. 25. Reverse Nodes in k-Group[H]k个一组翻转链表

    题目 Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. ...

  6. xmake从入门到精通10:多个子工程目标的依赖配置

    xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验. 本文主要详细讲解下,如果在一个项目中维护和生成多个 ...

  7. 图解 SQL 里的各种 JOIN

    约定 下文将使用两个数据库表 Table_A 和 Table_B 来进行示例讲解,其结构与数据分别如下: mysql> SELECT * FROM Table_A ORDER BY PK ASC ...

  8. 极*Java速成教程 - (5)

    Java语言基础 容器 这个世界是有序的,将Java对象零散地放到内存中是不符合世界常理的,特别是有一大组相似的甚至不知道有多少数据的时候.把Java对象装进盒子里可以有序收纳,这个盒子就叫容器. 初 ...

  9. java基础语法详细介绍

    一.概述 1.java语言概述 是SUN(Stanford University Network,斯坦福大学网络公司 ) 1995年推出的一门高级编程语言; java之父---James Goslin ...

  10. echarts markLine 辅助线非直线设置

    效果图: 用例option: option = { title: { text: '未来一周气温变化', subtext: '纯属虚构' }, tooltip: { trigger: 'axis' } ...