【莫队】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个询问的答案。
题目分析
一个区间[l,r]产生贡献即$number_{i,j}\equiv 0\ ({\rm mod}\ p)$.
按照常见套路来说,应该把区间拆成关于端点的式子。用$pre[i]$表示前$i$位在十进制下的数值,那么即$number_{i,j}=pre[j]-10^{j-i+1}*pre[i-1]$。将式子移项发现左右两边形如$f(r)=f(l-1)$(据说这是一种经典的莫队套路)那么于此已经将区间问题转化为关于单点的可$O(1)$修改的子问题了。
之后的操作就相对套路:将$n+1$个$f(i)$(不要忘记统计$f(0)$)预先离散化处理;然后常规莫队操作。
注意莫队要先修改再更新!
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
const int maxn = ; int blk[maxn];
struct QRs
{
int l,r,id;
bool operator < (QRs a) const
{
if (blk[l]==blk[a.l]) return r < a.r;
return blk[l] < blk[a.l];
}
}q[maxn];
char s[maxn];
int p,n,m,cnt,tot,size,inv10;
int lbd,rbd,lSd[maxn],rSd[maxn];
int ans[maxn],sum[maxn],pre[maxn],t[maxn]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
int qmi(int a, int b)
{
int ret = ;
while (b)
{
if (b&) ret = 1ll*ret*a%p;
b >>= , a = 1ll*a*a%p;
}
return ret;
}
void lAdd(int lbd)
{
rSd[sum[lbd]]++, tot+=rSd[sum[lbd-]], lSd[sum[lbd-]]++;
}
void rAdd(int rbd)
{
lSd[sum[rbd-]]++, tot+=lSd[sum[rbd]], rSd[sum[rbd]]++;
}
void lErase(int lbd)
{
lSd[sum[lbd-]]--, tot-=rSd[sum[lbd-]], rSd[sum[lbd]]--;
}
void rErase(int rbd)
{
rSd[sum[rbd]]--, tot-=lSd[sum[rbd]], lSd[sum[rbd-]]--;
}
int main()
{
freopen("bignum.in","r",stdin);
freopen("bignum.out","w",stdout);
p = read(), scanf("%s",s+);
n = strlen(s+), size = sqrt(n+0.5)+;
if (p==||p==){
for (int i=; i<=n; i++)
{
ans[i] = ans[i-], sum[i] = sum[i-];
if ((s[i]-'')%p==) ans[i]++, sum[i] += i;
}
m = read();
for (int i=; i<=m; i++)
{
int l = read(), r = read();
printf("%d\n",sum[r]-sum[l-]-(ans[r]-ans[l-])*(l-));
}
return ;
}
for (int i=; i<=n; i++) blk[i] = i/size, pre[i] = (pre[i-]*10ll%p+s[i]-'')%p;
inv10 = qmi(, p-);
for (int i=, pr=; i<=n; i++)
t[i] = sum[i] = 1ll*pre[i]*pr%p, pr = 1ll*pr*inv10%p;
std::sort(t, t+n+), cnt = std::unique(t, t+n+)-t-;
for (int i=; i<=n; i++)
sum[i] = std::lower_bound(t, t+cnt+, sum[i])-t+;
m = read();
for (int i=; i<=m; i++) q[i].l = read(), q[i].r = read(), q[i].id = i;
std::sort(q+, q+m+);
lbd = , rbd = ;
for (int i=; i<=m; i++)
{
while (lbd < q[i].l) lErase(lbd++);
while (lbd > q[i].l) lAdd(--lbd);
while (rbd > q[i].r) rErase(rbd--);
while (rbd < q[i].r) rAdd(++rbd);
ans[q[i].id] = tot;
}
for (int i=; i<=m; i++) printf("%d\n",ans[i]);
return ;
}
END
【莫队】bzoj4542: [Hnoi2016]大数的更多相关文章
- [BZOJ4542] [Hnoi2016] 大数 (莫队)
Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个 ...
- bzoj4542 [Hnoi2016]大数 莫队+同余
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4542 题解 我们令 \(f_i\) 表示从 \(i\) 到 \(n\) 位组成的数 \(\bm ...
- BZOJ4542: [Hnoi2016]大数
Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个 ...
- bzoj4542: [Hnoi2016]大数(莫队)
这题...离散化...$N$和$n$搞错了...查了$2h$...QAQ 考虑$s[l...r]$,可以由两个后缀$suf[l]-suf[r+1]$得到$s[l...r]$代表的数乘$10^k$得到的 ...
- 【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+ ...
- 【bzoj5452】[Hnoi2016]大数(莫队)
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4542 首先若p=2,5则这题就是道傻逼题,前缀和搞一下没了.如果p为其他质数,那么可以 ...
- 洛谷P3245 [HNOI2016]大数(莫队)
题意 题目链接 Sol 莫队板子题.. 维护出每个位置开始的字符串\(mod P\)的结果,记为\(S_i\) 两个位置\(l, r\)满足条件当且仅当\(S_l - S_r = 0\),也就是\(S ...
随机推荐
- docker镜像删除
1. 查看镜像 docker images [-q] 只列出image id [-a] 列出所有的image 2. 查看运行的镜像 docker ps [-q] 只列出container id [-a ...
- js 对象深拷贝
/* *p需要拷贝的对象 * */ var deepCopy=function(p, c) { var c = c || {}; for (var i in p) { if (typeof p[i] ...
- Codeforces Round #562 (Div. 2) A.Circle Metro
链接:https://codeforces.com/contest/1169/problem/A 题意: The circle line of the Roflanpolis subway has n ...
- codeforces840E In a Trap
好巧妙啊,感觉从来没有用过按位dp的trick,也没有用过树上链分块的trick 挂个链,全程看他的思路写的,当然lych帮我理解了最难懂的一部分 首先这里有个玄学的分块 每个点统计它上面256(其实 ...
- echart option属性
option 图表选项,包含图表实例任何可配置选项: 公共选项 , 组件选项 , 数据选项 名称 描述 {color}backgroundColor 全图默认背景,(详见backgroundColor ...
- WAMP3.1.10/Apache 设置站点根目录
网上的资料很多都不起作用了,都是说修改 WAMP\bin\apache\apache2.4.27\conf\httpd.conf 文件,但是修改了之后完全没有效果!! 最后,稀里糊涂的把 WAMP\b ...
- Maven--setting详解
settings.xml有什么用? 如果在Eclipse中使用过Maven插件,想必会有这个经验:配置settings.xml文件的路径. settings.xml文件是干什么的,为什么要配置它呢? ...
- 1137 - Sin your life sin公式 + 枚举
http://www.ifrog.cc/acm/problem/1137 和差化积公式, 变成2 * sin((x + y) / 2) * cos((x - y) / 2) + sin(n - (x ...
- java类在eclipse上打jar包,Linux上成功运行的实例
1 eclipse下的java项目结构如下图所示: 2 打包的步骤如下: 3 修改minifest.mf文件: 4 .上传需要的三方jar包们和主类打的jar(案例是topV.jar)并且执行jav ...
- (转载)23种设计模式的uml图表示及通俗介绍
转载自: https://www.cnblogs.com/ningskyer/articles/3615312.html 0.分类 创建型模式 1.FACTORY2.BUILDER3.FACTORY ...