hdu6085 Rikka with Candies [bitset+想法]

来源:互联网 发布:drupal建站 编辑:程序博客网 时间:2024/06/08 14:19

题意:给你长度为n的a数组,长度为m的b数组,有q和询问,每次询问求有几对数(ai,bj)满足ai%bj=qi。

题解:对于每一个数x和模数y,区间[x+k*y,x+(k+1)*y)的结果都可以累加到答案区间[0,j),所以我们可以对于所有bi,我们用一个bitset(tmp)存它门与它门的倍数对取模为0的答案的影响,之后枚举取模为1~ma(询问最大值)的答案,将tmp不断左移。在每一次循环开始,假如当前枚举的i属于b数组,我们需要更新tmp,那么我们需要将i和i的倍数与tmp异或,去除对答案的影响(因为当模结果为i的时候,不可能存在模数大于等于模的结果的情况),避免重复增加答案。

AC代码:

#include<stdio.h>#include<bitset>#include<iostream>#include<string.h>using namespace std;bitset<50010>a,tmp,hh;int b[50005],q[50005],ans[50005],mark[50005];int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n,m,Q,k,maa=0,ma=0;        scanf("%d%d%d",&n,&m,&Q);        memset(mark,0,sizeof(mark));        a.reset();        tmp.reset();        for(int i=0;i<n;i++)        {            scanf("%d",&k);            a[k]=1;            maa=max(maa,k);        }        for(int i=0;i<m;i++)        {            scanf("%d",&b[i]);            mark[b[i]]=1;        }        for(int i=0;i<Q;i++)            scanf("%d",&q[i]),ma=max(ma,q[i]);        for(int i=0;i<m;i++)            for(int j=0;j<=maa;j+=b[i])                tmp.flip(j);        for(int i=0;i<=ma;i++)        {            if(mark[i])for(int j=i;j<=maa;j+=i)tmp.flip(j);            hh=(tmp&a);            ans[i]=hh.count()%2;            tmp<<=1;            tmp[maa+1]=0;        }        for(int i=0;i<Q;i++)            printf("%d\n",ans[q[i]]);    }}