传送门

\(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. NOI 2002 贪吃的九头龙

    树形dp #include<bits/stdc++.h> #define N 305 using namespace std; struct LEB{ int to,nxt,w; }e[N ...

  2. A1042. Shuffling Machine

    Shuffling is a procedure used to randomize a deck of playing cards. Because standard shuffling techn ...

  3. IDEA或者WebStorm关闭JS文件的黄色提示

    这个编译器虽然好用,但是友好的提醒(语法校验)太多啦 解决: 在右下角有个小人儿 然后更改提示级别

  4. java equals和hashcode方法

    equals()方法比较两个对象的引用是否相同 hashcode()方法比较两个对象的哈希码是否相同

  5. CodeForces922E DP//多重背包的二进制优化

    https://cn.vjudge.net/problem/1365218/origin 题意 一条直线上有n棵树 每棵树上有ci只鸟 在一棵树底下召唤一只鸟的魔法代价是costi 每召唤一只鸟,魔法 ...

  6. Java 中的悲观锁和乐观锁的实现

    一.定义 1.悲观锁:即很悲观,每次拿数据的时候都觉得数据会被人更改,所以拿数据的时候就把这条记录锁掉,这样别人就没法改这条数据了,一直到你的锁释放. 2.乐观锁:即很乐观,查询数据的时候总觉得不会有 ...

  7. docker安装优化

    1.优化 #关闭防火墙 [root@docker03 ~]# systemctl stop firewalld.service [root@docker03 ~]# systemctl disable ...

  8. hadoop 开发环境搭建

    一,安装java环境 添加java环境变量 vi /etc/profile   # add by tank export JAVA_HOME=/data/soft/jdk/jdk1.7.0_71 ex ...

  9. Systemd 添加自定义服务(开机自启动)

    Systemd 简介:https://fedoraproject.org/wiki/Systemd/zh-cn 一.service unit 常用命令,以 mysql 服务为例 # 开机启动 syst ...

  10. float clearfix

    Float float 属性的原本作用是: 为了实现文字环绕效果 float 父元素高度塌陷实现文字环绕效果 float 固定一列宽的自适应布局 float 多列布局` float 固定一列宽的自适应 ...