[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 }
View Code

 

posted @ 2016-06-28 09:31  czllgzmzl  阅读(140)  评论(0编辑  收藏  举报