题目描述

给出一个数字串,多次询问一段区间有多少个子区间对应的数为P的倍数。其中P为质数。

输入

第一行一个整数:P。第二行一个串:S。第三行一个整数:M。接下来M行,每行两个整数 fr,to,表示对S 的子串S[fr…to]的一次询问。注意:S的最左端的数字的位置序号为 1;例如S为213567,则S[1]为 2,S[1…3]为 213。

N,M<=100000,P为素数

输出

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

样例输入

11
121121
3
1 6
1 5
1 4

样例输出

5
3
2


题解

莫队算法

设 $b[i]=S[i...n]\ \text{mod}\ p$ ,那么 $S[l,r]$ 为 $p$ 的倍数,当且仅当: $\frac{b[l]-b[r+1]}{10^{r-l}}\ \text{mod}\ p=0$ 。

当 $p=2$ 或 $p=5$ 时,直接通过数字串末位判断是不是 $p$ 的倍数。设 $v[i]=[i\ \text{mod}\ p=0]$ ,维护 $v[i]$ 和 $v[i]·i$ 的前缀和即可快速得出答案。

当 $p\neq 2$ 且 $p\neq 5$ 时,$p$ 与 $10$ 互质。此时条件简化为:$b[l]\equiv b[r+1]\ (\text{mod}\ p)$ 。

因此原问题转化为:求 $[l,r+1]$ 内 $b$ 值相等的数对的数目。

将 $b$ 离散化,使用莫队算法,用桶维护离散化后的某个 $b$ 的出现次数,指针移动时统计答案即可。

时间复杂度 $O(n\sqrt n)$

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
using namespace std;
typedef long long ll;
ll p;
char str[N];
namespace task1
{
ll s1[N] , s2[N];
void solve()
{
int n , m , i , l , r;
scanf("%s%d" , str + 1 , &m) , n = strlen(str + 1);
for(i = 1 ; i <= n ; i ++ )
{
s1[i] = s1[i - 1] , s2[i] = s2[i - 1];
if((str[i] - '0') % p == 0) s1[i] ++ , s2[i] += i;
}
while(m -- )
{
scanf("%d%d" , &l , &r);
printf("%lld\n" , s2[r] - s2[l - 1] - (l - 1) * (s1[r] - s1[l - 1]));
}
}
}
namespace task2
{
struct data
{
int l , r , bl , id;
bool operator<(const data &a)const {return bl == a.bl ? r < a.r : bl < a.bl;}
}q[N];
int a[N] , mp[N];
ll b[N] , v[N] , ans[N];
void solve()
{
int n , m , i , si , lp = 1 , rp = 0;
ll t = 1 , now = 0;
scanf("%s%d" , str + 1 , &m) , n = strlen(str + 1) , si = (int)sqrt(n);
for(i = n ; i ; i -- , t = t * 10 % p) v[i] = b[i] = (b[i + 1] + (str[i] - '0') * t) % p;
v[n + 1] = 0 , sort(v + 1 , v + n + 2);
for(i = 1 ; i <= n + 1 ; i ++ ) a[i] = lower_bound(v + 1 , v + n + 2 , b[i]) - v;
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &q[i].l , &q[i].r) , q[i].r ++ , q[i].bl = (q[i].l - 1) / si , q[i].id = i;
sort(q + 1 , q + m + 1);
for(i = 1 ; i <= m ; i ++ )
{
while(lp > q[i].l) now += mp[a[--lp]] , mp[a[lp]] ++ ;
while(rp < q[i].r) now += mp[a[++rp]] , mp[a[rp]] ++ ;
while(lp < q[i].l) mp[a[lp]] -- , now -= mp[a[lp++]];
while(rp > q[i].r) mp[a[rp]] -- , now -= mp[a[rp--]];
ans[q[i].id] = now;
}
for(i = 1 ; i <= m ; i ++ ) printf("%lld\n" , ans[i]);
}
}
int main()
{
scanf("%lld" , &p);
if(p == 2 || p == 5) task1::solve();
else task2::solve();
return 0;
}

【bzoj4542】[Hnoi2016]大数 莫队算法的更多相关文章

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

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

  2. bzoj4542 [Hnoi2016]大数 莫队+同余

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4542 题解 我们令 \(f_i\) 表示从 \(i\) 到 \(n\) 位组成的数 \(\bm ...

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

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

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

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

  5. 【BZOJ4540】[Hnoi2016]序列 莫队算法+单调栈

    [BZOJ4540][Hnoi2016]序列 Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,a ...

  6. [bzoj4540][Hnoi2016][序列] (莫队算法+单调栈+st表)

    Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-1,ar.若1≤l≤s≤t≤r≤n,则称a ...

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

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

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

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

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

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

随机推荐

  1. 20155323刘威良第二次实验 Java面向对象程序设计

    20155323刘威良第二次实验 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 ...

  2. jq移除最后一个class的值

    $(".his_pg_jl li").on("click",function() {//挂一个点击事件 $(this).addClass('back_img') ...

  3. js日期控件遇到的问题

    一.问题: 在web项目里有很多时候需要使用日期控件来完成相关的功能,但是日期控件的日期格式又和我们的需求不符 那么,就需要我们来自定义日期的格式完成需求 二.解决: 1.取月末: (1)强制取值: ...

  4. javaWeb项目-文件下载的消息头和编码问题

    一.问题: 做web项目经常提到的一个需求就是页面的文件下载,那么下载的时候在后台为什么要设置响应消息头?为什么这样设置? 二.解决: 1.例子 //设置响应的消息头response.setConte ...

  5. 成都Uber优步司机奖励政策(4月17日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  6. 1130: [POI2008]POD Subdivision of Kingdom

    1130: [POI2008]POD Subdivision of Kingdom https://lydsy.com/JudgeOnline/problem.php?id=1130 分析: 有效状态 ...

  7. MYSQL中日期与字符串间的相互转换

    一.字符串转日期 下面将讲述如何在MYSQL中把一个字符串转换成日期: 背景:rq字段信息为:20100901 1.无需转换的: SELECT * FROM tairlist_day WHERE rq ...

  8. superset 安装测试,基于windows 和 centos7.x

    1.刚开始在windows平台测试搭建,报各种问题,搭建可以参考官网https://superset.incubator.apache.org/installation.html#deeper-sql ...

  9. SpringBoot (1) idea下的环境搭建及demo

    1.Spring Boot简介 wiki上的介绍: Spring Boot是Spring的常规配置解决方案,用于创建可以“运行”的独立的,生产级的基于Spring的应用程序.[22]它预先配置了Spr ...

  10. No.03---Vue学习之路之模块化组织

    前两篇讲解了一下 Vuex 的基本使用方法,可是在实际项目中那么写肯定是不合理的,如果组件太多,不可能把所有组件的数据都放到一个 store.js 中的,所以就需要模块化的组织 Vuex,首先看一下 ...