HDU6085Rikka with Candies

来源:互联网 发布:java selenium教程 编辑:程序博客网 时间:2024/06/11 02:46

题目链接

题意

​ 存在两个长度分别为 n,m 的数组 A,B 。有 q 个询问,每个询问给出一个数字 k ,可以得到使得 AimodBj=k 的种数。求该种数的奇偶性。

分析

​ 由于只需要求出种数的奇偶性,容易发现奇偶性的变化和2进制中亦或的结果相同。于是想到利用位操作来进行优化。对于Bi ,可以不断的枚举区间 [kBi,(k+1)Bi1] ,而这一段区间中值 kBi+dBi 取模的结果为 d ,即该区间对Bi 取模结果为区间 [0,Bi1] 。于是根据 Ai 的值将取放置到区间中的对应位置,再不断枚举区间 [kBi,(k+1)Bi1] 和区间 [0,B1] 做亦或操作。询问时只要查询对应位的01值即可。实现时发现bitset没有区间操作的功能,所有利用unsigned long long 手动实现了bitset。最后复杂度为 O(n264) 。=-=赛时比较蠢,采用移位的方式将高位置零。本机和测评机果然还是与区别,猜测是左移过程中高位补1导致一直Wa。。赛后采用&操作的方式将高位置零就过了。。。果然还是太菜了啊。实现过程可以看代码。

代码

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;#define ULL unsigned long long#define MAXN 50050struct Bitset{    ULL bit[1600];    void reset(){        memset(bit,0,sizeof(bit));    }    void flip(int pos){        bit[pos>>6]^=1llu<<(pos&63);    }    bool judge(int pos){        return bit[pos>>6]&(1llu<<(pos&63));    }    void}A,ans;int b[MAXN];ULL prebit[66];int main(){    int T,n,m,q,a,mx;    cin>>T;    prebit[0]=1;    for(int i=1;i<64;++i)        prebit[i]=prebit[i-1]|(1ll<<i);    while(T--){        scanf("%d %d %d",&n,&m,&q);        A.reset();        ans.reset();        mx=0;        for(int i=0;i<n;++i){            scanf("%d",&a);            A.flip(a);            mx=max(a,mx);        }        for(int i=0;i<m;++i){            scanf("%d",&b[i]);            for(int j=0;j*b[i]<=mx;++j){                int len=j*b[i];                int idx1=len>>6,p1=len&63;                len+=b[i]-1;                int idx2=len>>6,p2=len&63;                if(idx1==idx2){                    ULL tmp=A.bit[idx1]>>p1;                    tmp&=prebit[p2-p1];                    ans.bit[0]^=tmp;                }                else{                    int curidx=0,curpos=0;                    ULL tmp=A.bit[idx1]>>p1;                    tmp&=prebit[63-p1];                    ans.bit[0]^=tmp;                    curpos=63-p1;                    for(int k=idx1+1;k<idx2;++k){                        if(curpos==63){                            curidx++;                            ans.bit[curidx]^=A.bit[k];                        }                        else{                            tmp=A.bit[k]<<(curpos+1);                            ans.bit[curidx++]^=tmp;                            tmp=A.bit[k]>>p1;                            tmp&=prebit[curpos];                            ans.bit[curidx]^=tmp;                        }                    }                    if(curpos==63){                        curidx++;                        tmp=A.bit[idx2]&prebit[p2];                        ans.bit[curidx]^=tmp;                    }                    else{                        if(p2<p1){                            tmp=A.bit[idx2]&prebit[p2];                            tmp<<=curpos+1;                            ans.bit[curidx]^=tmp;                        }                        else{                            tmp=A.bit[idx2]<<(curpos+1);                            ans.bit[curidx++]^=tmp;                            tmp=A.bit[idx2]>>p1;                            tmp&=prebit[p2-p1];                            ans.bit[curidx]^=tmp;                        }                    }                }            }        }        while(q--){            int k;            scanf("%d",&k);            if(ans.judge(k))                printf("1\n");            else                printf("0\n");        }    }}
原创粉丝点击