【CF472G】【XSY2112】Design Tutorial 压位

来源:互联网 发布:关键词排名优化小技巧 编辑:程序博客网 时间:2024/06/13 22:35

题目大意

  给出两个01序列AB

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

  0011110101的距离为2

  Q次询问,每次询问给出p1,p2,len

  求ap1,ap1+1ap1+len1bp1,bp1+1bp1+len1两个子串的汉明距离

  n2×105,q4×105

题解

  wys【挑战】弱化版

  暴力碾分块系列

  把axax+63压成一个64位整数,每次暴力统计。

  时间复杂度:O(nq64)

代码

#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\n",ans);    }    return 0;}
原创粉丝点击