[BZOJ4542] [Hnoi2016] 大数 (莫队)
Description
小 B 有一个很大的数 S,长度达到了 N 位;这个数可以看成是一个串,它可能有前导 0,例如00009312345
。小B还有一个素数P。现在,小 B 提出了 M 个询问,每个询问求 S 的一个子串中有多少子串是 P 的倍数(0 也
是P 的倍数)。例如 S为0077时,其子串 007有6个子串:0,0,7,00,07,007;显然0077的子串007有6个子串都是素
数7的倍数。
Input
第一行一个整数:P。第二行一个串:S。第三行一个整数:M。接下来M行,每行两个整数 fr,to,表示对S 的
子串S[fr…to]的一次询问。注意:S的最左端的数字的位置序号为 1;例如S为213567,则S[1]为 2,S[1…3]为 2
13。N,M<=100000,P为素数
Output
输出M行,每行一个整数,第 i行是第 i个询问的答案。
Sample Input
121121
3
1 6
1 5
1 4
Sample Output
3
2
//第一个询问问的是整个串,满足条件的子串分别有:121121,2112,11,121,121。
HINT
Source
2016.4.19新加数据一组
Solution
把n个后缀组成的数字全部对p取模。
若s[l] ~ s[n]的余数和s[r] ~ s[n]的余数相同,那么s[l] ~ s[r - 1]区间内的数字就是p的倍数(l < r)
这里有例外:当p = 2或p = 5时不成立。
然后这个题就变成经典莫队题了:给定一个序列,每次询问[l, r]内有多少对相同的数
每一个余数i给一个计数器ba[i](需离散化),记录[l, r]中这个数出现了几次,区间长度±1时答案改变值为ba[i]。
然后。。。原数据里没有p = 2或p = 5的情况。。。所以就没有然后了。然而BZOJ加了组数据
p = 2或p = 5时,用两个数组分别表示[1, i]中2或5的倍数时有多少种情况及有多少个数末尾是2或5的倍数,用前缀和维护。这部分就很简单了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll sqn, lst[], cd[], ba[], ans[];
struct query
{
ll id, l, r;
bool operator < (const query &rhs) const
{
if(l / sqn == rhs.l / sqn) return r < rhs.r;
return l / sqn < rhs.l / sqn;
}
}q[];
char s[];
map<ll, ll> Map;
int main()
{
ll n, m, p, l = , r = , cur = , bt = ;
scanf("%lld%s%lld", &p, s + , &m);
n = strlen(s + ), sqn = (ll)sqrt(n * 1.0);
if(p != && p != )
{
for(ll i = n; i; i--)
{
bt = bt * % p;
lst[i] = (lst[i + ] + (s[i] - ) * bt) % p;
cd[i] = lst[i];
}
sort(cd + , cd + n + );
for(ll i = ; i <= n + ; i++)
Map[cd[i]] = i;
for(ll i = ; i <= n + ; i++)
lst[i] = Map[lst[i]];
for(ll i = ; i <= m; i++)
{
scanf("%lld%lld", &q[i].l, &q[i].r);
q[i].id = i, q[i].r++;
}
sort(q + , q + m + );
for(ll i = ; i <= m; i++)
{
while(r < q[i].r) cur += ba[lst[++r]]++;
while(l > q[i].l) cur += ba[lst[--l]]++;
while(l < q[i].l) cur -= --ba[lst[l++]];
while(r > q[i].r) cur -= --ba[lst[r--]];
ans[q[i].id] = cur;
}
for(ll i = ; i <= m; i++)
printf("%lld\n", ans[i]);
}
else
{
for(ll i = ; i <= n; i++)
if(!((s[i] - ) % p))
ba[i] = ba[i - ] + , cd[i] = cd[i - ] + i;
else
ba[i] = ba[i - ], cd[i] = cd[i - ];
for(ll i = ; i <= m; i++)
{
scanf("%lld%lld", &l, &r);
printf("%lld\n", cd[r] - cd[l - ] - (ba[r] - ba[l - ]) * (l - ));
}
}
return ;
}
[BZOJ4542] [Hnoi2016] 大数 (莫队)的更多相关文章
- bzoj4542 [Hnoi2016]大数 莫队+同余
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4542 题解 我们令 \(f_i\) 表示从 \(i\) 到 \(n\) 位组成的数 \(\bm ...
- 【BZOJ4542】[Hnoi2016]大数 莫队
[BZOJ4542][Hnoi2016]大数 Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个 ...
- 【bzoj4542】[Hnoi2016]大数 莫队算法
题目描述 给出一个数字串,多次询问一段区间有多少个子区间对应的数为P的倍数.其中P为质数. 输入 第一行一个整数:P.第二行一个串:S.第三行一个整数:M.接下来M行,每行两个整数 fr,to,表示对 ...
- BZOJ.4542.[HNOI2016]大数(莫队)
题目链接 大数除法是很麻烦的,考虑能不能将其条件化简 一段区间[l,r]|p,即num[l,r]|p,类似前缀,记后缀suf[i]表示[i,n]的这段区间代表的数字 于是有 suf[l]-suf[r+ ...
- 洛谷P3245 [HNOI2016]大数(莫队)
题意 题目链接 Sol 莫队板子题.. 维护出每个位置开始的字符串\(mod P\)的结果,记为\(S_i\) 两个位置\(l, r\)满足条件当且仅当\(S_l - S_r = 0\),也就是\(S ...
- [BZOJ4542] [JZYZOJ2014][Hnoi2016] 大数(莫队+离散化)
正经题解在最下面 http://blog.csdn.net/qq_32739495/article/details/51286548 写的时候看了大神的题解[就是上面那个网址],看到下面这段话 观察题 ...
- bzoj 4542: [Hnoi2016]大数 (莫队)
Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个 ...
- [HNOI2016]序列(莫队,RMQ)
[HNOI2016]序列(莫队,RMQ) 洛谷 bzoj 一眼看不出来怎么用数据结构维护 然后还没修改 所以考虑莫队 以$(l,r-1) -> (l,r)$为例 对答案的贡献是$\Sigma_ ...
- 【莫队】bzoj4542: [Hnoi2016]大数
挺有意思的,可以仔细体味一下的题:看白了就是莫队板子. Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小 ...
随机推荐
- centos6下从源码安装setuptools和pip
1. 下载setuptools及pip的源码包 setuptools与pip都是python的模块 setuptools源码包: https://pypi.python.org/pypi/setupt ...
- vs code 使用git
1.下载git https://git-scm.com/ 2. git 全局设置 git config --global user.name "xxxx" git config - ...
- kaggle-titanic 数据分析过程
1. 引入所有需要的包 # -*- coding:utf-8 -*- # 忽略警告 import warnings warnings.filterwarnings('ignore') # 引入数据处理 ...
- Apache服务器安装-apache已经卸载,如何删除注册在系统的服务
cmd进入windows的命令行客户端,执行:sc delete apache 注意:以管理员的身份删除,同理,此方法也可以删除其他类似的服务.例如sc delete MongoDB.
- Shell脚本查看linux系统性能瓶颈(转)
Shell脚本查看linux系统性能瓶颈(转自:http://blog.51cto.com/lizhenliang/1687612) [root@test ~]# cat show_sys_info. ...
- 【2016北京集训测试赛(十六)】 River (最大流)
Description Special Judge Hint 注意是全程不能经过两个相同的景点,并且一天的开始和结束不能用同样的交通方式. 题解 题目大意:给定两组点,每组有$n$个点,有若干条跨组 ...
- C++中结构体与类的区别(struct与class的区别)
转载来源:http://blog.sina.com.cn/s/blog_48f587a80100k630.html C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据 ...
- Shell 脚本实践
1. 脚本判断命令输出是否为空 (1)判断字符串为空 if [ "$str" = "" ] if [ x"$str" = x ] if ...
- 转:彻底搞清referrer和origin
在http协议中有这两个字段,之前一直隐隐约约的觉得是,一种标记请求来源的方法(的确是),但是更细致的对这两个字段的比较却没有一个清楚的认识. referrer 到底是referer还是referre ...
- WINDOWS的错误代码对应的故障
WINDOWS的错误代码对应的故障 0000 操作已成功完成. 0001 错误的函数. 0002 系统找不到指定的文件. 0003 系统找不到指定的路径. 0004 系统无法打开文件. 0005 拒绝 ...