BZOJ4542: [Hnoi2016]大数

莫队= =
对于等于2或5的情况分类讨论

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
char c;
inline void read(int &a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<1)+(a<<3)+c-'0',c=getchar();}
inline void read(ll &a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<1)+(a<<3)+c-'0',c=getchar();}

int Len;
int L[100001];
inline void Get()
{do L[0]=getchar();while(L[0]<'0'||L[0]>'9');while(L[Len]>='0'&&L[Len]<='9')L[++Len]=getchar();}
ll p;
int Size;
struct Q
{
    int l,r,no,ans;
    inline friend bool operator <(Q a,Q b)
    {return a.l/Size^b.l/Size?a.l/Size<b.l/Size:a.r<b.r;}
}a[100001];
int ba[100001],cd[100001];
int lpos,rpos;
ll A[100001];
int Time[100001];
ll Ans[100001];
int Val;
map<ll,int>S;
int Rec[100001];
void Del(int x)
{
    int pl;
    if(!Rec[x])Rec[x]=pl=S[A[x]];
    else pl=Rec[x];
    Time[pl]--;
    Val-=Time[pl];
}
void Add(int x)
{

    int pl;
    if(!Rec[x])Rec[x]=pl=S[A[x]];
    else pl=Rec[x];
    Val+=Time[pl];
    Time[pl]++;
}

int ans,Con;
int main()
{
   read(p);
   int m;
   Get();
   read(m);
   Size=sqrt(m)+1;
// if(!S[0])S[0]=++Con;
// time[S[0]]++;
   if(p==2||p==5)
   { 
   ll l,r;
   for(ll i=1;i<=Len;i++)
            if(!((L[i-1]-'0')%p))
                ba[i]=ba[i-1]+1,cd[i]=cd[i-1]+i;
            else
                ba[i]=ba[i-1],cd[i]=cd[i-1];
        for(ll i=1;i<=m;i++)read(l),read(r),printf("%lld\n",cd[r]-cd[l-1]-(ba[r]-ba[l-1])*(l-1));
   return 0;
   }
   for(int i=1;i<=m;i++)
   read(a[i].l),read(a[i].r),a[i].no=i,a[i].r++;
   sort(a+1,a+1+m);
   lpos=1,rpos=0;
   ll base=1;
   for(int i=Len;i;i--)
    {
        base*=10;
        base%=p;
     A[i]=(A[i+1]+base*(L[i-1]-'0'))%p;
     if(!S[A[i]])S[A[i]]=++Con;
    }

   for(int j=1;j<=m;j++)
       {
          while(rpos<a[j].r)
          Add(++rpos);
          while(lpos>a[j].l)Add(--lpos);
          while(lpos<a[j].l)Del(lpos++);
          while(rpos>a[j].r)Del(rpos--);
          Ans[a[j].no]=Val;
       }   
   for(int i=1;i<=m;i++)printf("%d\n",Ans[i]);
   return 0;
}

你可能感兴趣的:(BZOJ4542: [Hnoi2016]大数)