HNOI016 大数 莫队

我们处理一个前缀或者后缀就变成了区间相同数字的个数了

引用LZX的来说就是 http://blog.csdn.net/lzxzxx/article/details/51197592

/* ***********************************************
Author        :BPM136
Created Time  :2016/4/20 9:48:45
File Name     :C.cpp
************************************************ */

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<bitset>
#include<queue>
#include<ctime>
#include<set>
#include<utility>
#include<vector>
#include<functional>
#include<numeric>
#include<memory>
#include<iterator>
#define LL long long
#define DB double
#define LB long double
#define UL unsigned long
#define ULL unsigned long long
#define get(a,i) a&(1<<(i-1))
#define PAU putchar(0)
#define ENT putchar(32)
#define clr(a,b) memset(a,b,sizeof(a))
#define fo(_i,_a,_b) for(int _i=_a;_i<=_b;_i++)
#define fd(_i,_a,_b) for(int _i=_a;_i>=_b;_i--)
#define efo(_i,_a) for(int _i=last[_a];_i!=0;_i=e[_i].next)
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
#define mkd(x) freopen(#x".in","w",stdout);
#define setlargestack(x) int size=x<<20;char *p=(char*)malloc(size)+size;__asm__("movl %0, %%esp\n" :: "r"(p));
#define end system("pause")
using namespace std;
LL read()
{
         LL f=1,d=0;char s=getchar();
         while (s<48||s>57){if (s==45) f=-1;s=getchar();}
         while (s>=48&&s<=57){d=d*10+s-48;s=getchar();}
         return f*d;
}
LL readln()
{
       LL f=1,d=0;char s=getchar();
       while (s<48||s>57){if (s==45) f=-1;s=getchar();}
       while (s>=48&&s<=57){d=d*10+s-48;s=getchar();}
       while (s!=10) s=getchar();
       return f*d;
}
inline void write(LL x)
{
    if(x==0){putchar(48);return;}if(x<0)putchar(45),x=-x;
    int len=0,buf[20];while(x)buf[len++]=x%10,x/=10;
    for(int i=len-1;i>=0;i--)putchar(buf[i]+48);return;
}
inline void writeln(LL x){write(x);ENT;}

#define N 100005
int a[N];
LL MOD,val[N],A[N],hash[N],nm=0;
struct question
{
	int l,r,id;
	int bid;
	int ans;
}Q[N];
int n,m;
char s[N];
int sb;

bool cmpQ(question a,question b){
	if(a.bid!=b.bid)return a.bid<b.bid;
	if(a.r!=b.r)return a.r<b.r;
	return a.l<b.l;
}

bool cmpid(question a,question b){
	return a.id<b.id;
}

void prework(){
	A[++n]=0;LL po10=1;
	fd(i,n,1){
		(A[i]=A[i+1]+a[i]*po10)%=MOD;
		hash[++nm]=A[i];
		(po10*=10)%=MOD;
	}
	sort(hash+1,hash+nm+1);
	fo(i,1,n){
		A[i]=lower_bound(hash+1,hash+nm+1,A[i])-hash;
	}
	sort(Q+1,Q+m+1,cmpQ);
}

void work(){
	int l=1,r=0,anss=0;
	fo(i,1,m){
		while(r<Q[i].r)anss+=val[A[++r]]++;
		while(r>Q[i].r)anss-=--val[A[r--]];
		while(l>Q[i].l)anss+=val[A[--l]]++;
		while(l<Q[i].l)anss-=--val[A[l++]];
		Q[i].ans=anss;
	}
	sort(Q+1,Q+m+1,cmpid);
}

int main()
{
//	file(C);
	MOD=read();
	scanf("%s",s+1);
	n=strlen(s+1);
	fo(i,1,n)a[i]=s[i]-'0';
	m=read();  sb=sqrt(n);
	fo(i,1,m){
		Q[i].l=read(),Q[i].r=read();Q[i].r++;
		Q[i].id=i;
		Q[i].bid=(Q[i].l-1)/sb+1;
	}
	prework();
#define DEBUG look
//	fo(i,1,m)cout<<Q[i].l<<' '<<Q[i].r<<endl;
	work();
	fo(i,1,m){
		cout<<Q[i].ans<<endl;
	}
	return 0;
}


你可能感兴趣的:(莫队)