bzoj3067: Hyperdrome

不难想到前缀和后按位hash,其实就是当成一个二进制数嘛

有hash的奇技淫巧,不%不知道...

 

第一次在bzoj跑到前十真是感天动地 神仙请屏蔽自带巨大常数的蒟蒻

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int _=1e2;
const int maxn=3*1e5+_;
const int maxc=2*26+10;
const int hmod=8388607;
 
LL Bin[maxn];
struct Hash
{
    int first[hmod],last[hmod],nxt[maxn];
    int len,c[maxn];LL d[maxn];
    void insert(LL k)
    {
        int x=k&hmod;
        for(int i=first[x];i;i=nxt[i])
            if(d[i]==k){c[i]++;return ;}
             
        int now=++len;
        if(first[x]==0)first[x]=last[x]=now;
        else nxt[last[x]]=now,last[x]=now;
        d[now]=k,c[now]++;
    }   
    int getsum(LL k)
    {
        int x=k&hmod;
        for(int i=first[x];i;i=nxt[i])
            if(d[i]==k)return c[i];
        return 0;
    }
}H;
 
int n,a[maxn];bool v[maxc];
char ss[maxn];
int main()
{
    Bin[0]=1;for(int i=1;i<maxc;i++)Bin[i]=Bin[i-1]*2;
    scanf("%d%s",&n,ss+1);
     
    LL ans=0; LL sum=0;
    H.insert(sum);
    for(int i=1;i<=n;i++)
    {
        if('a'<=ss[i]&&ss[i]<='z')a[i]=ss[i]-'a'+1;
        else a[i]=ss[i]-'A'+27;
        v[a[i]]=true;
         
        sum^=Bin[a[i]-1];
        ans=ans+H.getsum(sum);
        for(int j=1;j<=52;j++)
            if(v[j])ans=ans+H.getsum(sum^Bin[j-1]);
         
        H.insert(sum);
    }
    printf("%lld\n",ans);
     
    return 0;
}

 

posted @ 2019-03-08 07:19  AKCqhzdy  阅读(171)  评论(0编辑  收藏  举报