• bzoj 4866: [Ynoi2017]由乃的商场之旅


    设第i个字母的权值为1<<i,则一个可重集合可以重排为回文串,当且仅当这个集合的异或和x满足x==x&-x,用莫队维护区间内有多少对异或前缀和,异或后满足x==x&-x,这样端点移动的代价为字符集大小+1=27,因此时间复杂度为$O(27nsqrt{m})$

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    char buf[3000000],*ptr=buf-1;
    int _(){
        int x=0,c=*++ptr;
        while(c<48)c=*++ptr;
        while(c>47)x=x*10+c-48,c=*++ptr;
        return x;
    }
    typedef unsigned int u32;
    const int P=2939999,N=61007;
    int n,q,xs[N][27];
    int hx[P][2],idp=0;
    int getid(int x){
        int w=x%P;
        while(hx[w][1]){
            if(hx[w][0]==x)return hx[w][1];
            if((w+=12347)>=P)w-=P;
        }
        hx[w][0]=x;
        return hx[w][1]=++idp;
    }
    u32 as[N],pos[N],B,ans=0,t[N*27];
    struct Q{
        int l,r,id;
    }qs[N];
    bool operator<(Q a,Q b){
        if(pos[a.l]!=pos[b.l])return pos[a.l]<pos[b.l];
        if(a.r!=b.r)return (a.r<b.r)^(pos[a.l]&1);
        return a.id<b.id;
    }
    void ins(int*x){
        for(int i=0;i<=26;++i)ans+=t[x[i]];
        ++t[x[26]];
    }
    void del(int*x){
        --t[x[26]];
        for(int i=0;i<=26;++i)ans-=t[x[i]];
    }
    int main(){
        fread(buf,1,sizeof(buf),stdin)[buf]=0;
        n=_();q=_();
        B=(n+1)/sqrt(q+1)+1;
        for(int i=0;i<=n;++i)pos[i]=i/B;
        while(*ptr<'a')++ptr;
        for(int i=1;i<=n;++i)xs[i][26]=xs[i-1][26]^1<<*ptr++-'a';
        for(int i=0;i<=n;++i){
            for(int j=0;j<26;++j)xs[i][j]=xs[i][26]^1<<j;
        }
        for(int i=0;i<=n;++i){
            for(int j=0;j<=26;++j)xs[i][j]=getid(xs[i][j]);
        }
        for(int i=0;i<q;++i){
            qs[i].l=_()-1;
            qs[i].r=_();
            qs[i].id=i;
        }
        std::sort(qs,qs+q);
        int L=1,R=0;
        for(int i=0;i<q;++i){
            int l=qs[i].l,r=qs[i].r;
            while(L>l)ins(xs[--L]);
            while(R<r)ins(xs[++R]);
            while(L<l)del(xs[L++]);
            while(R>r)del(xs[R--]);
            as[qs[i].id]=ans;
        }
        for(int i=0;i<q;++i)printf("%u
    ",as[i]);
        return 0;
    }
  • 相关阅读:
    [背包问题][二进制优化] Jzoj P4224 食物
    [并查集][排序] Jzoj P4223 旅游
    [哈夫曼树][优先队列] Bzoj P4198 荷马史诗
    [hash][差分][虚树] Jzoj P6011 天天爱跑步
    [dp] Jzoj P6012 荷马史诗
    [dp][递归] Jzoj P4211 送你一棵圣诞树
    [数学] Jzoj P3912 超氧化钾
    堆学习笔记(未完待续)(洛谷p1090合并果子)
    [AC自动机]luogu P2444 病毒
    [概率期望][DP]luogu P3830 随机树
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7416296.html
Copyright © 2020-2023  润新知