bzoj2506

题解:

分段

当p<=100时候,暴力枚举%p=k的个数

当p>100是,暴力枚举j=qp+k的个数

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=200005,M=10005,K=105;
int a[N],b[N],m,n,k[N],f1[K][K],f2[M],f[N],p[N],ans[N];
int cmp(int x,int y)
{
    return a[x]<a[y];
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)scanf("%d",&b[i]);
    for (int i=1;i<=m;i++)
     {
         scanf("%d%d%d%d",&a[i+m],&a[i],&p[i],&k[i]);
         a[i+m]--;f[i]=i;f[i+m]=i+m;p[i+m]=p[i];k[i+m]=k[i];
     }
    sort(f+1,f+m+m+1,cmp);
    int l=1;
    while (a[f[l]]==0)l++;
    for (int i=1;i<=n;i++)
     {
         for (int j=1;j<=100;j++)f1[j][b[i]%j]++;
         f2[b[i]]++;
         while (a[f[l]]==i)
          {
              if (f[l]>m)
               {
                   if (p[f[l]]>100)
                    for (int j=k[f[l]];j<=10000;j+=p[f[l]])ans[f[l]-m]-=f2[j];
                   else ans[f[l]-m]-=f1[p[f[l]]][k[f[l]]];
                   l++;
               }
              else
             {
                   if (p[f[l]]>100)
                    for (int j=k[f[l]];j<=10000;j+=p[f[l]])ans[f[l]]+=f2[j];
                   else ans[f[l]]+=f1[p[f[l]]][k[f[l]]];            
                l++;     
             } 
          }
     } 
    for (int i=1;i<=m;i++)printf("%d
",ans[i]); 
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8569912.html