题目传送门

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. 乱入Spring+Mybatis

    新进入一个项目,写了一个功能,就是提供一个服务(service),该服务能够查询和插入.完成后,想要用junit测试一下:发现到了DAO底层注入的SqlSession字段为空:才意识到这是一个Spri ...

  2. 2018.03.28 python-pandas groupby使用

    groupby 分组统计 1.根据某些条件将数据分组 2.对每个组独立应用函数 3.将结果合并到一个数据结构中 Dataframe在行或列上分组,将一个函数应用到各个分组并产生一个新值,然后函数执行结 ...

  3. Delphi IDE使用的一些主要技巧

    Delphi IDE使用的一些主要技巧 1.查找和替换 (1)<ctrl>+F[1]:选择页“Find”,进行查找,则根据查找方向继续查找.选择页“Findin Files”,则进行该工程 ...

  4. sql 、linq、lambda 查询语句

    http://www.cnblogs.com/lei2007/archive/2011/07/21/2113161.html

  5. cocos2dx基础篇(8) 开关按钮CCControlSwitch

    [3.x] (1)去掉 “CC” (2)对象类 CCObject 改为 Ref (3)标签类 LabelTTF 改为 Label (4)CCControlEvent 改为强枚举 Control::Ev ...

  6. Struts2框架学习笔记1

    1,框架概述 1.1,什么是框架(了解) 将一些重复性的代码进行封装,简化程序员的编程操作,可以使得程序员在编码中把更多的精力放到业务需求的分析和理解上面,相当于一个半成品软件. 1.2,三大框架(掌 ...

  7. python每日一练:0000题

    **第 0000 题:**将你的 QQ 头像(或者微博头像)右上角加上红色的数字,类似于微信未读信息数量那种提示效果. 类似于图中效果 示例代码: from PIL import Image,Imag ...

  8. 应用安全 - Web安全 - 远程控制管理工具 - 汇总

    菜刀 蚁剑 冰蝎 DarkCommet ADT windows/upexec/reverse_tcp set PEXEC xxx

  9. css文件引用

    #i1l{ background-color: chartreuse; height: 40px; } #i2l{ background-color: olivedrab; height: 40px; ...

  10. tarjan算法应用 割点 桥 双连通分量

    tarjan算法的应用. 还需多练习--.遇上题目还是容易傻住 对于tarjan算法中使用到的Dfn和Low数组. low[u]:=min(low[u],dfn[v])--(u,v)为后向边,v不是u ...