【LG3245】[HNOI2016]大数

题面

洛谷

题解

60pts

拿vector记一下对于以每个位置为右端点符合要求子串的左端点,

则每次对于一个询问,扫一遍右端点在vector里面二分即可,

虽然空间是平方级别的但是因为数据水还是可以过60的

100pts

记\([i,n]\)表示的数为\(num_i\),则一段区间\([l,r]\)所表示的数为

\[\frac {num_l-num_{r+1}}{10^{r-l+1}}
\]

题目就要使\(\frac {num_l-num_{r+1}}{10^{r-l+1}}\% P=0\)

当\(gcd(10^{r-l+1},P)=1\)时,我们用将每一个\(num\% P\)离散化后莫队维护一下一个值出现的次数即可,

那么对于\(gcd(10^{r-l+1},P)\neq 1\),可以知道此时\(P=2\)或\(5\),因为这时候整除关系只与数的最后一位有关,

转移也非常显然。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAX_N = 1e5 + 5;
const int LEN = 320;
char a[MAX_N];
int N, P, Q, bel[MAX_N];
struct Query { int l, r, id; } q[MAX_N];
bool operator < (const Query &lhs, const Query &rhs) {
if (bel[lhs.l] ^ bel[rhs.l]) return bel[lhs.l] < bel[rhs.l];
else return (bel[lhs.l] & 1) ? lhs.r < rhs.r : lhs.r > rhs.r;
}
int s[MAX_N], h[MAX_N], pw[MAX_N];
long long Ans, Cnt, bln[MAX_N], ans[MAX_N];
void Ins(int x) { Ans += bln[s[x]], ++bln[s[x]]; }
void Ers(int x) { --bln[s[x]], Ans -= bln[s[x]]; }
void insl(int x) { Cnt += (a[x] - '0') % P == 0, Ans += Cnt; }
void dell(int x) { Ans -= Cnt, Cnt -= (a[x] - '0') % P == 0; }
void insr(int x, int l, int r) { if ((a[x] - '0') % P == 0) ++Cnt, Ans += r - l + 1; }
void delr(int x, int l, int r) { if ((a[x] - '0') % P == 0) Ans -= r - l + 1, --Cnt; }
int main () {
#ifndef ONLINE_JUDGE
freopen("cpp.in", "r", stdin);
#endif
scanf("%d%s%d", &P, a + 1, &Q); N = strlen(a + 1);
for (int i = 1; i <= Q; i++) scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i;
for (int i = 1; i <= N; i++) bel[i] = (i - 1) / LEN + 1;
sort(&q[1], &q[Q + 1]);
pw[0] = 1; for (int i = 1; i <= N; i++) pw[i] = 10ll * pw[i - 1] % P;
for (int i = N; i; i--) s[i] = (s[i + 1] + 1ll * (a[i] - '0') * pw[N - i] % P) % P;
for (int i = 1; i <= N; i++) h[i] = s[i];
sort(&h[1], &h[N + 2]); int size = unique(&h[1], &h[N + 2]) - h - 1;
for (int i = 1; i <= N; i++) s[i] = lower_bound(&h[1], &h[size + 1], s[i]) - h - 1;
int ql = 1, qr = 0;
if (P != 2 && P != 5) {
for (int i = 1; i <= Q; i++) {
++q[i].r;
while (ql < q[i].l) Ers(ql), ++ql;
while (ql > q[i].l) --ql, Ins(ql);
while (qr < q[i].r) ++qr, Ins(qr);
while (qr > q[i].r) Ers(qr), --qr;
ans[q[i].id] = Ans;
}
} else {
for (int i = 1; i <= Q; i++) {
while (ql > q[i].l) --ql, insl(ql);
while (qr < q[i].r) ++qr, insr(qr, ql, qr);
while (ql < q[i].l) dell(ql), ++ql;
while (qr > q[i].r) delr(qr, ql, qr), --qr;
ans[q[i].id] = Ans;
}
}
for (int i = 1; i <= Q; i++) printf("%lld\n", ans[i]);
return 0;
}

【LG3245】[HNOI2016]大数的更多相关文章

  1. 4542: [Hnoi2016]大数

    4542: [Hnoi2016]大数 链接 分析: 如果p等于2或者5,可以根据最后一位直接知道是不是p的倍数,所以直接记录一个前缀和即可. 如果p不是2或者5,那么一个区间是p的倍数,当且仅当$\f ...

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

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

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

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

  4. BZOJ4542: [Hnoi2016]大数

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

  5. 4542: [Hnoi2016]大数

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

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

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

  7. [HNOI2016]大数

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

  8. bzoj 4542: [Hnoi2016]大数

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

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

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

随机推荐

  1. Jmeter入门--安装教程

    jmeter简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试静态和动 ...

  2. sql面试

    1.用一条SQL语句 查询出每门课都大于80分的学生姓名 name   kecheng   fenshu 张三     语文       81张三     数学       75李四     语文   ...

  3. 使用GTID给Galera集群做数据库异步复制

    一.为什么要做Galera集群异步复制 Galera集群解决了数据库高可用的问题,但是存在局限性,例如耗时的事务处理可能会导致集群性能急剧下降,甚至出现阻塞现象.而不幸的是,类似报表等业务需求就需要做 ...

  4. 小鸡G4工程款 上手体验

    前言:之前只是抱着试一试的态度在小鸡活动贴下报名,说实话之前并没有抱希望能够没选中.所以非常感谢小鸡团队给我的这次机会.这应该是我第一次参与厂家的内测活动.希望能给小鸡团队,给广大玩家带来一片实用的上 ...

  5. 制作 OS X El Capitan 启动盘

    制作 OS X El Capitan 启动盘 1. 下载系统盘的dmg格式 2. 直到出现了 3. 在命令行中找到 Install OS X El Capitan.app 4. 格式化你的U盘(U盘名 ...

  6. [翻译] CotEditor

    CotEditor https://github.com/coteditor/CotEditor CotEditor is a lightweight plain-text editor for OS ...

  7. java开发初识

    jdk目录相关介绍: bin:存放的是java的相关开发工具 db:顾名思义jre附带的轻量级数据库 include:存放的是调用系统资源的接口文件 jre:java的运行环境 lib:核心的类库 s ...

  8. Visual Studio 2013 Web开发新特性

    微软正式发布Visual Studio 2013 RTM版,微软还发布了Visual Studio 2013的最终版本..NET 4.5.1以及Team Foundation Server 2013. ...

  9. T-SQL 标识符

    在T-SQL语言中,对SQLServer数据库及其数据对象(比如表.索引.视图.存储过程.触发器等)需要以名称来进行命名并加以区分,这些名称就称为标识符. 通常情况下,SQLServer数据库.数据库 ...

  10. QT 登录记住密码方法之一:Qt QSettings读写配置文件

    不过本文写的是明文保存,最好还是加密一下,以防文件被非法读取 /**登录初始化的时候处理这部分操作*/ Settings cfg("user.ini",QSettings::Ini ...