【BZOJ4542】大数, 莫队
Time:2016.09.10 传送门 #include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define M 100003
#define LL long long
using namespace std;
int n,m;
int block[M],sum[M];
LL P,ans[M],a[M],b[M],cnt[M],T[M];
char s[M];
struct query{
int l,r,id;
}q[M];
int in()
{
int t=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') t=(t<<1)+(t<<3)+ch-48,ch=getchar();
return t;
}
bool cmp(query a,query b)
{
if (block[a.l]==block[b.l]) return a.r<b.r;
return block[a.l]<block[b.l];
}
void solve()
{
for (int i=1;i<=n;i++)
if ((P==2&&!(s[i]-'0'&1))||(P==5&&(s[i]=='5'||s[i]=='0')))
cnt[i]+=i,++T[i];
for (int i=1;i<=n;++i) cnt[i]+=cnt[i-1],T[i]+=T[i-1];
for (int i=1;i<=m;++i)
q[i]=(query){in(),in(),i},printf("%lldn",cnt[q[i].r]-cnt[q[i].l-1]-(T[q[i].r]-T[q[i].l-1])*(q[i].l-1));
}
main()
{
scanf("%lld",&P);
scanf("%s",s+1);
n=strlen(s+1);
m=in();
if (P==2||P==5) {solve();return 0;}
LL t=1;s[++n]='0';
for (int i=1;i<=m;++i) q[i]=(query){in(),in()+1,i};
for (int i=n;i>=1;--i)
a[i]=b[i]=(a[i+1]+t*(s[i]-'0'))%P,t=t*10%P;
sort(b+1,b+n+1);
b[0]=unique(b+1,b+n+1)-b-1;
for (int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+b[0]+1,a[i])-b;
block[0]=sqrt(n);
for (int i=1;i<=n;++i) block[i]=(i+1)/block[0];
sort(q+1,q+m+1,cmp);
int L=1,R=0;LL S=0;
for (int i=1;i<=m;++i)
{
for (int j=L-1;j>=q[i].l;--j)
S+=sum[a[j]]++;
for (int j=L;j<q[i].l;++j)
S-=--sum[a[j]];
for (int j=R+1;j<=q[i].r;++j)
S+=sum[a[j]]++;
for (int j=R;j>q[i].r;--j)
S-=--sum[a[j]];
L=q[i].l;R=q[i].r;ans[q[i].id]=S;
}
for (int i=1;i<=m;++i) printf("%lldn",ans[i]);
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |