【jzoj4744】【同余】【分段处理】

题目大意

这里写图片描述

解题思路

可以发现当p较小时可以预处理出%p后的前缀和,把询问挂在每个点分别处理。当p较大时可以开一个桶,枚举合法的原数统计答案不会很多。

code

#include<set>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LF double
#define LL long long
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a>b)?b:a)
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
using namespace std;
int const maxn=100000,mida=100,maxa=10000,inf=2147483647;
int n,m,gra1,gra2,a[maxn+10],cnt[mida+2][maxn+2],h[mida+2][maxn+2],pos1[maxn*65+10],val1[maxn*65+10],next1[maxn*65+10],pos2[maxn*65+10],val2[maxn*65+10],mo[maxn*65+10],next2[maxn*65+10],begin1[maxn+10],begin2[maxn+10],ans[maxn+10],mod=1000000007;
void insert1(int u,int v,int p){
    pos1[++gra1]=p;
    val1[gra1]=v;
    next1[gra1]=begin1[u];
    begin1[u]=gra1;
}
void insert2(int u,int m,int v,int p){
    pos2[++gra2]=p;
    val2[gra2]=v;
    mo[gra2]=m;
    next2[gra2]=begin2[u];
    begin2[u]=gra2;
}
int main(){
    freopen("d.in","r",stdin);
    freopen("d.out","w",stdout);
    scanf("%d%d",&n,&m);
    fo(i,1,n)
        scanf("%d",&a[i]);
    fo(i,1,m){
        int l,r,p,q;scanf("%d%d%d%d",&l,&r,&p,&q);
        if(p>mida){
            for(int j=q;j<=maxa;j+=p)
                insert1(l-1,j,-i),insert1(r,j,i);
        }
        else{
            insert2(l-1,p,q,-i),insert2(r,p,q,i);
        }
    }
    fo(i,1,n){
        int p=a[i];
        h[mida+1][p]=a[i];cnt[mida+1][p]++;
        fo(j,1,mida){
            int p=a[i]%j;
            h[j][p]=a[i]%j;cnt[j][p]++;
        }
        for(int j=begin1[i];j;j=next1[j])
            ans[abs(pos1[j])]+=cnt[mida+1][val1[j]]*((pos1[j]>0)?1:-1);
        for(int j=begin2[i];j;j=next2[j])
            ans[abs(pos2[j])]+=cnt[mo[j]][val2[j]]*((pos2[j]>0)?1:-1);
    }
    fo(i,1,m)printf("%d\n",ans[i]);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值