zoukankan      html  css  js  c++  java
  • 【CF472G】Design Tutorial 压位

    题目大意

      给出两个(01)序列(A)(B)

      汉明距离定义为两个长度相同的序列中,有多少个对应位置上的数字不一样

      (00111)(10101)的距离为(2)

      (Q)次询问,每次询问给出(p_1,p_2,len)

      求(a_{p_1},a_{p_1+1}ldots a_{p_1+len−1})(b_{p_1},b_{p_1+1}ldots b_{p_1+len−1})两个子串的汉明距离

      (nleq 2 imes{10}^5,qleq 4 imes {10}^5)

    题解

      wys【挑战】弱化版

      暴力碾分块系列

      把(a_xldots a_{x+63})压成一个(64)位整数,每次暴力统计。

      时间复杂度:(O(frac{nq}{64}))

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<ctime>
    #include<utility>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    char s1[200010];
    char s2[200010];
    ull a[200010];
    ull b[200010];
    int cnt[100010];
    int count(ull x)
    {
    	return cnt[x&0xffff]+cnt[(x>>16)&0xffff]+cnt[(x>>32)&0xffff]+cnt[(x>>48)&0xffff];
    }
    int main()
    {
    	int n,m,q;
    	scanf("%s%s%d",s1+1,s2+1,&q);
    	n=strlen(s1+1);
    	m=strlen(s2+1);
    	int i;
    	for(i=n;i>=1;i--)
    		a[i]=(a[i+1]>>1)|(s1[i]=='1'?(1ll<<63):0);
    	for(i=m;i>=1;i--)
    		b[i]=(b[i+1]>>1)|(s2[i]=='1'?(1ll<<63):0);
    	cnt[0]=0;
    	for(i=1;i<(1<<16);i++)
    		cnt[i]=cnt[i>>1]+(i&1);
    	int x,y,l;
    	for(i=1;i<=q;i++)
    	{
    		scanf("%d%d%d",&x,&y,&l);
    		x++;
    		y++;
    		int ans=0;
    		while(l>=64)
    		{
    			ans+=count(a[x]^b[y]);
    			x+=64;
    			y+=64;
    			l-=64;
    		}
    		if(l)
    			ans+=count((a[x]^b[y])>>(64-l));
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    SQL数据库数据优化SQL优化总结( 百万级数据库优化方案)
    三星S8相机黑画面解决
    三星Galaxy S8 刷机经验记录
    2018.12.02 Socket编程之初识Socket
    工作至今
    巧用std::shared_ptr全局对象释放单例内存
    C++标准库之迭代器
    Phone 3rd Recovery
    进电机之两相双极性步进电机仿真
    使用Pretues仿真Arduino驱动步进电机
  • 原文地址:https://www.cnblogs.com/ywwyww/p/8511318.html
Copyright © 2011-2022 走看看