传送门

\(HNOI2019\)前最后一题了qwq

这题要分情况,如果\(p=2\)或\(5\),那么只要区间内最后一个数字是\(p\)的倍数就好了,这个可以莫队,也有更优秀的做法.莫队做法可以看代码懒

否则,考虑一个数怎么表示,记\(s_i\)为前\(i\)为构成的数,可以知道区间\([i,j]\)的数应该是\(s_r-s_{l-1}*10^{r-l+1}\),现在要求这个数模\(p\)为0,那么也就是$$s_r-s_{l-1}*10^{r-l+1}\equiv0\ (\mathrm{mod}\ p)$$

两边同时除掉\(10^r\),得到

\[s_r*10^{-r}-s_{l-1}*10^{-(l-1)}\equiv0\ (\mathrm{mod}\ p)
\]

如果位置\(i\)的权值为\(s_i*10^{-i}\),那么一个区间\([i,j]\)的答案就是\([i-1,j]\)中每种权值相同的点对个数,这个还是比较好写的

#include<bits/stdc++.h>
#define LL long long
#define db long double
#define il inline using namespace std;
const int N=1e5+10;
il LL rd()
{
LL x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int p,a[N],n,sqt,q,be[N];
LL an[N],na;
char cc[N];
struct qu
{
int l,r,i;
bool operator < (const qu &bb) const {return be[l]!=be[bb.l]?l<bb.l:r<bb.r;}
}qq[N];
int fpow(int a,int b){a%=p;int an=1;while(b){if(b&1) an=1ll*an*a%p;a=1ll*a*a%p,b>>=1;} return an;}
namespace ct1
{
int cn;
void wk()
{
sort(qq+1,qq+q+1);
for(int i=1,l=1,r=0;i<=q;++i)
{
while(r<qq[i].r) ++r,cn+=a[r]%p==0,na+=(a[r]%p==0?r-l+1:0);
while(r>qq[i].r) na-=(a[r]%p==0?r-l+1:0),cn-=a[r]%p==0,--r;
while(l<qq[i].l) na-=cn,cn-=a[l]%p==0,++l;
while(l>qq[i].l) --l,cn+=a[l]%p==0,na+=cn;
an[qq[i].i]=na;
}
}
}
namespace ct2
{
int cn[N],b[N],m;
void wk()
{
int pp=fpow(10,p-2);
b[++m]=0;
for(int i=1,j=1,sm=0;i<=n;++i)
{
sm=1ll*sm*10%p+a[i],j=1ll*j*pp%p;
a[i]=1ll*sm*j%p;
b[++m]=a[i];
}
sort(b+1,b+m+1),m=unique(b+1,b+m+1)-b-1;
for(int i=0;i<=n;++i) a[i]=lower_bound(b+1,b+m+1,a[i])-b;
for(int i=1;i<=q;++i) --qq[i].l;
sort(qq+1,qq+q+1);
for(int i=1,l=0,r=-1;i<=q;++i)
{
while(r<qq[i].r) ++r,++cn[a[r]],na+=cn[a[r]]-1;
while(r>qq[i].r) na-=cn[a[r]]-1,--cn[a[r]],--r;
while(l<qq[i].l) na-=cn[a[l]]-1,--cn[a[l]],++l;
while(l>qq[i].l) --l,++cn[a[l]],na+=cn[a[l]]-1;
an[qq[i].i]=na;
}
}
} int main()
{
p=rd();
scanf("%s",cc+1);
n=strlen(cc+1);
sqt=sqrt(n);
for(int i=1;i<=n;++i) a[i]=cc[i]-'0',be[i]=i/sqt;
q=rd();
for(int i=1;i<=q;++i) qq[i].l=rd(),qq[i].r=rd(),qq[i].i=i;
if(p==2||p==5) ct1::wk();
else ct2::wk();
for(int i=1;i<=q;++i) printf("%lld\n",an[i]);
return 0;
}

luogu P3245 [HNOI2016]大数的更多相关文章

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

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

  2. 洛谷P3245 [HNOI2016]大数 【莫队】

    题目 题解 除了\(5\)和\(2\) 后缀数字对\(P\)取模意义下,两个位置相减如果为\(0\),那么对应子串即为\(P\)的倍数 只用对区间种相同数个数\(x\)贡献\({x \choose 2 ...

  3. 【LG3245】[HNOI2016]大数

    [LG3245][HNOI2016]大数 题面 洛谷 题解 60pts 拿vector记一下对于以每个位置为右端点符合要求子串的左端点, 则每次对于一个询问,扫一遍右端点在vector里面二分即可, ...

  4. 4542: [Hnoi2016]大数

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

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

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

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

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

  7. BZOJ4542: [Hnoi2016]大数

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

  8. 4542: [Hnoi2016]大数

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

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

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

随机推荐

  1. redis 指令文档

    参考:https://redis.io/commands http://www.runoob.com/redis/redis-lists.html redis: 打开一个 cmd 窗口 使用cd命令切 ...

  2. Macbook外接显示器模糊解决方法

    解决方法(此方法经本人测试失败) 下载这个http://www.elias.cn/uploads/Mac/patch-edid.zip.如果链接失效可以使用https://gist.github.co ...

  3. A1125. Chain the Ropes

    Given some segments of rope, you are supposed to chain them into one rope. Each time you may only fo ...

  4. ANIS与UNICODE字符格式转换:MultiByteToWideChar() 和WideCharToMultiByte() 函数

    资料来自: http://blog.csdn.net/holamirai/article/details/47948745 http://www.cnblogs.com/wanghao111/arch ...

  5. 第十二节,TensorFlow读取数据的几种方法以及队列的使用

    TensorFlow程序读取数据一共有3种方法: 供给数据(Feeding): 在TensorFlow程序运行的每一步, 让Python代码来供给数据. 从文件读取数据: 在TensorFlow图的起 ...

  6. 工具类:Colletions ,Arrays(静态导入,可变参数,强循环)

    一.Collecti 专门用来操作集合的工具类,没有构造函数,全静态方法. 常用方法: static <T extends Comparable<? super T>> voi ...

  7. python 类的介绍

    使用面向对象的优点: 1.能够更好的设计软件架构 2.维护软件模块 3.易于架构和组件的重用 类的定义: 构造函数:初始化用,写不写都可以,默认为空 类属性:属于类的对象 方法属性:不属于类的对象 私 ...

  8. 温故知新 —— Floyd算法

    什么?Floyd?sb O(n ^ 3) 算法早不用了,右上角红叉吧.我之前虽然也认识过 Floyd 算法的重要性,不过多少也是这么想的.然而最近三天连续 rand 到了好几道有关的题目,让我彻底重新 ...

  9. 关键字(6):trigger触发器

    trigger是个特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作(insert,delete,update)时就会激活它执行.触发器经常用于加强数据的 ...

  10. M1-Flask-Day1

    前情概要 1.flask的基本使用 - 配置 - 路由 - 视图 - 请求与响应相关 - 模板 2.flask基于装饰器实现的路由 - 基本操作 - functools - 带参数的装饰器 - 源码剖 ...