BZOJ-4542: [Hnoi2016]大数 (莫队算法)
Posted 可惜没如果=_=
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ-4542: [Hnoi2016]大数 (莫队算法)相关的知识,希望对你有一定的参考价值。
4542: [Hnoi2016]大数
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1637 Solved: 568
[Submit][Status][Discuss]
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
11
121121
3
1 6
1 5
1 4
121121
3
1 6
1 5
1 4
Sample Output
5
3
2
//第一个询问问的是整个串,满足条件的子串分别有:121121,2112,11,121,121。
3
2
//第一个询问问的是整个串,满足条件的子串分别有:121121,2112,11,121,121。
HINT
2016.4.19新加数据一组
Source
T了两个点什么鬼qwq
1 #include "bits/stdc++.h" 2 using namespace std; 3 typedef long long LL; 4 const int MAX=1e6+5; 5 LL n,m,p,bas,pos[MAX]; 6 LL a[MAX],b[MAX],d[MAX],an[MAX],ans; 7 LL ab[MAX],cd[MAX]; 8 char s[MAX]; 9 struct Node{ 10 int id; 11 int l,r; 12 bool operator < (const Node &tt) const { 13 if (pos[l]!=pos[tt.l]) 14 return pos[l]<pos[tt.l]; 15 return r<tt.r; 16 } 17 }que[MAX]; 18 inline LL read(){ 19 LL an=0,x=1;char c=getchar(); 20 while (c<‘0‘ || c>‘9‘) {if (c==‘-‘) x=-1;c=getchar();} 21 while (c>=‘0‘ && c<=‘9‘) {an=an*10+c-‘0‘;c=getchar();} 22 return an*x; 23 } 24 int main(){ 25 freopen ("huge.in","r",stdin);freopen ("huge.out","w",stdout); 26 LL i,j,cnt=1,x,y; 27 scanf("%lld\n",&p);scanf("%s",s+1); n=strlen(s+1);bas=(LL)sqrt(n*1.0); 28 if (p==2 || p==5){ 29 for (i=1;i<=n;i++){ 30 if ((s[i]-‘0‘)%p==0) 31 ab[i]=ab[i-1]+1,cd[i]=cd[i-1]+i; 32 else ab[i]=ab[i-1],cd[i]=cd[i-1]; 33 } 34 m=read(); 35 for (i=1;i<=m;i++){ 36 x=read(),y=read(); 37 printf("%lld\n",cd[y]-cd[x-1]-(ab[y]-ab[x-1])*(x-1)); 38 } 39 return 0; 40 } 41 for (i=n;i>=1;i--){ 42 cnt=(cnt*10)%p; 43 b[i]=a[i]=((s[i]-‘0‘)*cnt+a[i+1])%p; 44 } 45 sort(b+1,b+n+1); 46 for (i=1;i<=n+1;i++) a[i]=lower_bound(b+1,b+n+1,a[i])-b; 47 m=read(); 48 for (i=1;i<=m;i++){ 49 que[i].id=i; 50 que[i].l=read(),que[i].r=read();que[i].r++; 51 } 52 sort(que+1,que+m+1); 53 int L=1,R=0; 54 for (i=1;i<=m;i++){ 55 while(R<que[i].r) ans+=ab[a[++R]]++; 56 while(L>que[i].l) ans+=ab[a[--L]]++; 57 while(L<que[i].l) ans-=--ab[a[L++]]; 58 while(R>que[i].r) ans-=--ab[a[R--]]; 59 an[que[i].id]=ans; 60 } 61 for (i=1;i<=m;i++) 62 printf("%lld\n",an[i]); 63 return 0; 64 }
以上是关于BZOJ-4542: [Hnoi2016]大数 (莫队算法)的主要内容,如果未能解决你的问题,请参考以下文章