[BZOJ 4542][Hnoi2016]大数:莫队

点击这里查看原题

首先可以考虑,除了2和5之外, 10k 不是任何素数的倍数,因此可以先解决p不为2或5的情况。对从每个位置开始的到末尾结束的子串求一下模p的值,再离散化一下(因为题目没有给出p的范围),这样的话如果两个位置i,j模p的值相同,那么S[i…j-1]就是符合条件的一个子串。莫队处理即可
再来考虑下2和5的情况,可以发现,如果某个数是2或5的倍数,那么它的个位一定也是2或5的倍数,于是前缀和处理即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=1e5+5;
int q,pos[M],n,cnt[M],tot;
bool vis[M];
char s[M];
ll res[M],ans[M],now,v[M],t[M],p;
struct no{
    int l,r,id;
    bool operator<(const no &b)const{
        return pos[l]==pos[b.l]?r<b.r:pos[l]<pos[b.l];
    }
}qu[M];
void solve1(){
    for(int i=1;i<=n;i++){
        res[i]=res[i-1];
        cnt[i]=cnt[i-1];
        if((s[i]-'0')%p==0){
            res[i]+=i;
            cnt[i]++;
        }
    }
    while(q--){
        int l,r;
        scanf("%d%d",&l,&r);
        ll tmp=res[r]-res[l-1]-(ll)(cnt[r]-cnt[l-1])*(l-1);
        printf("%lld\n",tmp);
    }
}
void update(int x){
    now-=(ll)(cnt[v[x]]-1)*cnt[v[x]]/2;
    if(!vis[x]) cnt[v[x]]++;
    else cnt[v[x]]--;
    vis[x]^=1;
    now+=(ll)(cnt[v[x]]-1)*cnt[v[x]]/2;
}
int main(){
    scanf("%lld%s%d",&p,s+1,&q);
    n=strlen(s+1);
    if(p==2||p==5){
        solve1();
        return 0;
    }
    for(int i=1,block=sqrt(n)+0.5;i<=n;i++) pos[i]=(i-1)/block+1;
    ll x=0,fac=1;
    for(int i=n,x=0,fac=1;i;i--){
        x=(x+(ll)(s[i]-'0')*fac)%p;
        fac=(ll)fac*10%p;
        v[i]=t[i]=x;
    }
    v[++n]=t[n]=0;
    sort(t+1,t+n+1);
    tot=unique(t+1,t+n+1)-t-1;
    for(int i=1;i<=n;i++) v[i]=lower_bound(t+1,t+tot+1,v[i])-t;
    for(int i=1;i<=q;i++){
        scanf("%d%d",&qu[i].l,&qu[i].r);
        qu[i].r++;
        qu[i].id=i;
    }
    sort(qu+1,qu+q+1);
    int l=1,r=0;
    for(int i=1;i<=q;i++){
        for(int j=l;j<qu[i].l;j++) update(j);
        for(int j=r;j>qu[i].r;j--) update(j);
        for(int j=l-1;j>=qu[i].l;j--) update(j);
        for(int j=r+1;j<=qu[i].r;j++) update(j);
        l=qu[i].l,r=qu[i].r;
        ans[qu[i].id]=now;
    }
    for(int i=1;i<=q;i++) printf("%lld\n",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/SmallSXJ/article/details/74029793