bzoj4866: [Ynoi2017]由乃的商场之旅

真的是。。。异或前缀和没想到啊。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int read()
{
    int f=1,x=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int Bin[35];

int n,s[61000],lslen,ls[61000]; char ss[35];
int g[61000][30];

int m;
struct query{int l,r,id;}q[61000];int st[61000],block,as[61000];
bool cmp(query n1,query n2){return st[n1.l]==st[n2.l]?n1.r<n2.r:st[n1.l]<st[n2.l];}

//----------------------init--------------------------------------- 

int v[61000],ans,l,r;
void add_l(int p)
{
    ans+=v[s[p-1]]+(s[r]==s[p-1]);
    for(int j=1;j<=26;j++)
        if(g[p-1][j]!=-1)ans+=v[g[p-1][j]]+(s[r]==g[p-1][j]);
    v[s[p-1]]++;
}
void add_r(int p)
{
    v[s[p-1]]++;ans+=v[s[p]];
    for(int j=1;j<=26;j++)
        if(g[p][j]!=-1)ans+=v[g[p][j]];
}
void del_l(int p)
{
    v[s[p-1]]--;ans-=v[s[p-1]]+(s[r]==s[p-1]);
    for(int j=1;j<=26;j++)
        if(g[p-1][j]!=-1)ans-=v[g[p-1][j]]+(s[r]==g[p-1][j]);
}
void del_r(int p)
{
    ans-=v[s[p]];
    for(int j=1;j<=26;j++)
        if(g[p][j]!=-1)ans-=v[g[p][j]];
    v[s[p-1]]--;
}
void solve()
{
    l=1,r=0;ans=0;
    memset(v,0,sizeof(v));
    for(int i=1;i<=m;i++)
    {
        while(q[i].l<l)l--, add_l(l);
        while(r<q[i].r)r++, add_r(r);
        while(l<q[i].l)del_l(l), l++;
        while(q[i].r<r)del_r(r), r--;
        as[q[i].id]=ans;
    }
}

//------------------------莫队---------------------------------- 

int erfen(int d)
{
    int l=1,r=lslen;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(ls[mid]==d)return mid;
        
        if(ls[mid]<d)l=mid+1;
        else r=mid-1;
    }
    return -1;
}

int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    Bin[1]=1;for(int i=2;i<=27;i++)Bin[i]=Bin[i-1]*2;    
    n=read();m=read();
    scanf("%s",ss+1); lslen=0;
    s[0]=0; ls[++lslen]=s[0];
    for(int i=1;i<=n;i++)
    {
        int x=ss[i]-'a'+1;
        s[i]=s[i-1]^Bin[x];
        ls[++lslen]=s[i];
    }
    sort(ls+1,ls+lslen+1);
    lslen=unique(ls+1,ls+lslen+1)-ls-1;
    
    for(int i=0;i<=n;i++)
    {
        g[i][0]=lower_bound(ls+1,ls+lslen+1,s[i])-ls;
        for(int j=1;j<=26;j++)
            g[i][j]=erfen(s[i]^Bin[j]);
        s[i]=g[i][0];
    }
    
    block=int(sqrt(double(n+1)));
    for(int i=1;i<=n;i++)st[i]=(i-1)/block+1;
    for(int i=1;i<=m;i++)
        q[i].l=read(), q[i].r=read(), q[i].id=i;
    sort(q+1,q+m+1,cmp);
    solve();
    for(int i=1;i<=m;i++)printf("%d\n",as[i]);
    return 0;
}

 

posted @ 2018-09-21 08:43  AKCqhzdy  阅读(259)  评论(0编辑  收藏  举报