题解 [HNOI2016]大数
题目大意
给出一个\(n\)个数的字符串,有\(m\)次查询,对于该串的子串\([l,r]\)有多少个子串满足是固定素数\(p\)的倍数。
思路
其实很简单,但是一开始想偏了。。。果然还是自己菜啊。。。
我们可以想到统计一下后缀和\(s[i]\),表示\([i,n]\)构成的数,那么,判断一个区间\([l,r]\)是不是\(p\)的倍数就等价于:
\]
我们发现如果\(\gcd(10,p)=1\)的话,分母就不会产生影响,于是判断条件就是:
\]
于是对于这种情况我们就可以用莫队\(\Theta(n\sqrt n)\)开桶记录答案。
如果\(\gcd(10,p)\not=1\)的话,那么\(p=2 \operatorname{or} 5\),我们发现这种情况对于区间\([l,r]\)判断是否的话直接判断第\(r\)位是不是\(2\operatorname{or}5\)的倍数即可。于是我们可以\(\Theta(n)\)解决这种情况。
果然还是自己菜了啊。。。这都没有看出来。。。
\(\texttt{Code}\)
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define ll long long
#define MAXN 200005
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
char S[MAXN];
ll sum,ans[MAXN];int n,m,p,un,s[MAXN],tmp[MAXN],bel[MAXN],cnt[MAXN];
namespace Subtask1{
struct node{
int l,r,id;
bool operator < (const node &p)const{return bel[l] != bel[p.l] ? l < p.l : r < p.r;}
}q[MAXN];
void cge (int x,int k){sum -= 1ll * cnt[x] * (cnt[x] - 1) / 2,cnt[x] += k,sum += 1ll * cnt[x] * (cnt[x] - 1) / 2;}
void Work (){
int siz = sqrt (n);
for (Int i = n,c = 1;i;-- i,c = 1ll * c * 10 % p) s[i] = (s[i + 1] + 1ll * c * (S[i] - '0') % p) % p,bel[i] = (i - 1) / siz + 1,tmp[i] = s[i];
sort (tmp + 1,tmp + n + 2);un = unique (tmp + 1,tmp + n + 2) - tmp - 1;for (Int i = 1;i <= n + 1;++ i) s[i] = lower_bound (tmp + 1,tmp + un + 1,s[i]) - tmp;
read (m);for (Int i = 1;i <= m;++ i) read (q[i].l,q[i].r),q[i].r ++,q[i].id = i;sort (q + 1,q + m + 1);int l = 1,r = 0;
for (Int i = 1;i <= m;++ i){
while (l < q[i].l) cge (s[l ++],-1);while (l > q[i].l) cge (s[-- l],1);
while (r < q[i].r) cge (s[++ r],1);while (r > q[i].r) cge (s[r --],-1);
ans[q[i].id] = sum;
}
for (Int i = 1;i <= m;++ i) write (ans[i]),putchar ('\n');
return ;
}
}
namespace Subtask2{
int snum[MAXN];ll ssum[MAXN];
void Work(){
for (Int i = 1;i <= n;++ i){
snum[i] = ((S[i] - '0') % p == 0);
ssum[i] = ssum[i - 1] + 1ll * ((S[i] - '0') % p == 0) * i;
}
read (m);
while (m --){
int l,r;read (l,r);
write (ssum[r] - ssum[l - 1] - (snum[r] - snum[l - 1]) * (l - 1)),putchar ('\n');
}
}
}
signed main(){
read (p),scanf("%s",S + 1),n = strlen (S + 1);
if (p == 2 || p == 5) Subtask2::Work ();
else Subtask1::Work ();
return 0;
}
题解 [HNOI2016]大数的更多相关文章
- 【LG3245】[HNOI2016]大数
[LG3245][HNOI2016]大数 题面 洛谷 题解 60pts 拿vector记一下对于以每个位置为右端点符合要求子串的左端点, 则每次对于一个询问,扫一遍右端点在vector里面二分即可, ...
- 【BZOJ4542】[Hnoi2016]大数 莫队
[BZOJ4542][Hnoi2016]大数 Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个 ...
- 4542: [Hnoi2016]大数
4542: [Hnoi2016]大数 链接 分析: 如果p等于2或者5,可以根据最后一位直接知道是不是p的倍数,所以直接记录一个前缀和即可. 如果p不是2或者5,那么一个区间是p的倍数,当且仅当$\f ...
- 题解-[HNOI2016]序列
题解-[HNOI2016]序列 [HNOI2016]序列 给定 \(n\) 和 \(m\) 以及序列 \(a\{n\}\).有 \(m\) 次询问,每次给定区间 \([l,r]\in[1,n]\),求 ...
- 4542: [Hnoi2016]大数
Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个 ...
- BZOJ.4542.[HNOI2016]大数(莫队)
题目链接 大数除法是很麻烦的,考虑能不能将其条件化简 一段区间[l,r]|p,即num[l,r]|p,类似前缀,记后缀suf[i]表示[i,n]的这段区间代表的数字 于是有 suf[l]-suf[r+ ...
- 【bzoj4542】[Hnoi2016]大数 莫队算法
题目描述 给出一个数字串,多次询问一段区间有多少个子区间对应的数为P的倍数.其中P为质数. 输入 第一行一个整数:P.第二行一个串:S.第三行一个整数:M.接下来M行,每行两个整数 fr,to,表示对 ...
- [BZOJ4542] [JZYZOJ2014][Hnoi2016] 大数(莫队+离散化)
正经题解在最下面 http://blog.csdn.net/qq_32739495/article/details/51286548 写的时候看了大神的题解[就是上面那个网址],看到下面这段话 观察题 ...
- 洛谷P3245 [HNOI2016]大数 【莫队】
题目 题解 除了\(5\)和\(2\) 后缀数字对\(P\)取模意义下,两个位置相减如果为\(0\),那么对应子串即为\(P\)的倍数 只用对区间种相同数个数\(x\)贡献\({x \choose 2 ...
随机推荐
- Spring系列之事物是如何管理的
前言 我们都知道Spring给我们提供了很多抽象,比如我们在操作数据库的过程中,它为我们提供了事物方面的抽象,让我们可以非常方便的以事物方式操作数据库.不管你用JDBC.Mybatis.Hiberna ...
- APMServ中Apache启动失败的原因
APMServ中Apache启动失败绝大多数的情况是因为APMServ得路径出错和80端口被占用,也有可能您使用的是WIN8系统,下面SJY根据不同情况告诉大家如何解决APMServ中Apache启动 ...
- Reinforcement Learning 强化学习入门
https://www.zhihu.com/question/277325426 https://github.com/jinglescode/reinforcement-learning-tic-t ...
- uniapp 封装 request 并 配置跨域,( 本地 + 线上 + 封装 )
找到上面这个 文件,不管是用 命令创建 还是 用 HBX 创建,都一样会有这个文件的,然后跟着截图复制粘贴就好了. // 这是配置本地能跨域的,或者你可以直接让后端给你设置请求头,避免了跨域. &qu ...
- SpringMVC-源码-图解
- aes加解密前后端-后台
一.web.xml: <filter> <filter-name>fastLoginFilter</filter-name> <filter-class> ...
- 植入式Web前端开发
在博客园.凡科建站和其他的一些CMS系统中,提供有允许管理者向网页中插入自定义HTML代码的功能,我将其称之为"植入式"的Web前端代码. 因为CSS和JavaScript可以直接 ...
- vue-admin-element 页面跳转
1.通过router-link 进行跳转 <router-link to="/china-quotation/business-function/quotation-request&q ...
- Apache网页优化
目录: 一.Apache网页优化概述 二.网页压缩 三.网页缓存 四.隐藏版本信息 五.Apache防盗链 一.Apache网页优化概述 在企业中,部署Apache后只采用默认的配置参数,会引发网站很 ...
- vue中如何深度监听一个对象?
大家都知道,Vue项目中对数据的监听,提供了一个很好的钩子watch,watch可以极其方便的监听我们常用数据类型值的变化,但通常当我们想监听一个对象中,某个属性值的变化时,很难达到我们预期的效果.那 ...