[bzoj2506] calc
莫队+暴力。。
对于>100的模数p,每次暴力查k,p+k,2p+k.....就好了。
对于<=100的模数,就在莫队的时候处理出来就好了。。。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=100233; 7 struct zs{int r,id,p,k;}a[maxn<<1]; 8 int i,j,k,n,m,mx,mx1; 9 int mp[maxn],ans[maxn<<1]; 10 int now[103][103],sm[10023]; 11 12 int ra;char rx; 13 inline int read(){ 14 rx=getchar(),ra=0; 15 while(rx<'0'||rx>'9')rx=getchar(); 16 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 17 } 18 bool cmp(zs a,zs b){return a.r<b.r;} 19 int main(){ 20 n=read(),m=read(); 21 for(i=1;i<=n;i++)mp[i]=read(),mx=max(mx,mp[i]);mx1=min(70,mx); 22 for(i=1;i<=m;i++) 23 a[i+m].r=read()-1,a[i].r=read(),a[i+m].p=a[i].p=read(),a[i+m].k=a[i].k=read(), 24 a[i+m].id=i+m,a[i].id=i; 25 sort(a+1,a+1+m+m,cmp);int top=1,m1=m<<1;register int j; 26 while(top<=m1&&a[top].r==0)top++; 27 for(i=1;i<=n;i++){ 28 sm[mp[i]]++; 29 for(j=1;j<=mx1;j++)now[j][mp[i]%j]++; 30 while(top<=m1&&a[top].r==i){ 31 int tmp=0; 32 if(a[top].p<=mx1)tmp=now[a[top].p][a[top].k]; 33 else for(j=a[top].k;j<=mx;j+=a[top].p)tmp+=sm[j]; 34 ans[a[top].id]=tmp; 35 top++; 36 } 37 if(top>m1)break; 38 } 39 for(i=1;i<=m;i++)printf("%d\n",ans[i]-ans[i+m]); 40 }