zoukankan      html  css  js  c++  java
  • 【分块】【bitset】hdu6085 Rikka with Candies

    给你数组A和B,A B中的元素大小都不超过5w,且两两不同。

    q次询问,每次给你个k,问你有多少对(i,j),满足A(i)%B(j)==k。

    如题目所言模拟bitset的过程,实质上是个分块,每块的大小定为63。

    一个小技巧是对于最终的那个数组w,分块后记63个w数组,每个数组最前面一块是零散的部分,大小从1~63,这样比较好操作。

    最后把63个w里面的每一位的值都异或起来,就是对应的k的答案。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int SZ=63;
    typedef unsigned long long ull;
    ull blo[805],b[67][805],lss[67];
    int T,n,m,q,sum=794,l[805],r[805],num[50005],sz[805];
    bool a[50005],c[50005];
    int main(){
    	int x;
    	scanf("%d",&T);
    	for(;T;--T){
    		memset(a,0,sizeof(a));
    		memset(blo,0,sizeof(blo));
    		memset(b,0,sizeof(b));
    		memset(lss,0,sizeof(lss));
    		memset(l,0,sizeof(l));
    		memset(r,0,sizeof(r));
    		memset(num,0,sizeof(num));
    		memset(sz,0,sizeof(sz));
    		memset(c,0,sizeof(c));
    		scanf("%d%d%d",&n,&m,&q);
    		for(int i=1;i<=n;++i){
    			scanf("%d",&x);
    			a[x]=1;
    		}
    		r[0]=-1;
    		for(int i=1;i<=sum;++i){
    			l[i]=r[i-1]+1;
    			r[i]=min(i*SZ-1,50000);
    			sz[i]=r[i]-l[i]+1;
    			for(int j=l[i],p=0;j<=r[i];++j,++p){
    				if(a[j]){
    					blo[i]|=((ull)1<<p);
    				}
    				num[j]=i;
    			}
    		}
    		for(;m;--m){
    			scanf("%d",&x);
    			for(int ql=0;ql<=50000;ql+=x){
    				int qr=min(ql+x-1,50000);
    				if(num[ql]==num[qr]){
    					int fls=ql-l[num[ql]];
    					lss[qr-ql+1]^=((blo[num[ql]]>>fls)&(((ull)1<<(qr-ql+1))-(ull)1));
    				}
    				else{
    					int ls=r[num[ql]]-ql+1;
    					for(int i=num[ql]+1,j=1;i<num[qr];++i,++j){
    						b[ls][j]^=blo[i];
    					}
    					int rs=qr-l[num[qr]]+1;
    					lss[ls]^=(blo[num[ql]]>>(sz[num[ql]]-ls));
    					b[ls][num[qr]-num[ql]]^=(blo[num[qr]]&(((ull)1<<rs)-(ull)1));
    				}
    			}
    		}
    		for(int i=1;i<=SZ;++i){
    			for(int j=0;j<i;++j){
    				c[j]^=((lss[i]>>j)&(ull)1);
    			}
    			int now=0,wei;
    			for(int k=i,p=1;k<=50000;++k,++p,++wei){
    				if(p%SZ==1){
    					++now;
    					wei=0;
    				}
    				c[k]^=((b[i][now]>>wei)&((ull)1));
    			}
    		}
    		for(;q;--q){
    			scanf("%d",&x);
    			printf("%d
    ",c[x]);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    对现有Hive的大表进行动态分区
    Hive表分区
    Hive常用的SQL命令操作
    Hadoop分布式安装
    Hadoop命令摘录
    HDFS基本知识整理
    Hive基本命令整理
    Hadoop
    淘宝数据魔方技术架构解析
    Eclipse 下 opennms 开发环境搭建
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7308919.html
Copyright © 2011-2022 走看看