zoukankan      html  css  js  c++  java
  • P5112 FZOUTSY

    P5112 FZOUTSY

    建个后缀自动机,当然这里得反着建
    找到最小的大于k的子串,相当于最小满足的子串,(endpos)最大,然后沿(parents)边都染成同一色
    同色的都满足后缀的最长公共前缀满足大于k,接下来就是莫队在树上跑

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const LL maxn=10000000;
    inline LL Read(){
        LL x=0,f=1; char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-') f=-1; c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=(x<<3)+(x<<1)+c-'0'; c=getchar();
        }return x*f;
    }
    LL n,m,K,last,nod,num,tot,size,pieces;
    LL col[maxn],ans[maxn],len[maxn],fail[maxn],son[maxn][7],head[maxn];
    LL belong[maxn],cnt[maxn];
    LL ch[500];
    char s[maxn];
    inline void Init(){
        last=n+1,nod=n+1;
        for(LL i=1;i<=n;++i)
            len[i]=i;
    }
    inline void Insert(LL c,LL now){
        LL p=last;
        last=now;
        while(p&&!son[p][c])
            son[p][c]=now,
            p=fail[p];
        if(!p)
            fail[now]=n+1;
        else{
            LL q=son[p][c];
            if(len[q]==len[p]+1)
                fail[now]=q;
            else{
                LL nq=++nod;
                len[nq]=len[p]+1;
                memcpy(son[nq],son[q],sizeof(son[q]));
                fail[nq]=fail[q], fail[q]=fail[now]=nq;
                while(p&&son[p][c]==q)
                    son[p][c]=nq,
                    p=fail[p];
            }
        }
    }
    struct code{
        LL to,next;
    }dis[maxn];
    inline void Add(LL u,LL v){
        dis[++num]=(code){v,head[u]},head[u]=num;
    }
    inline void Build(){
        for(LL i=1;i<=nod;++i)
            Add(fail[i],i);
    }
    void Dfs(LL u,LL co){
        if(u<=n)
            col[u]=co;
        if(co)
            for(LL i=head[u];i;i=dis[i].next)
                Dfs(dis[i].to,co);
        else
            for(LL i=head[u];i;i=dis[i].next){
            	LL v=dis[i].to;
                if(len[v]>=K)
                    Dfs(v,++tot);
                else
                    Dfs(v,0);
            }
    }
    struct node{
        LL l,r,id;
    }q[maxn];
    inline bool cmp(node x,node y){
        return (belong[x.l]^belong[y.l])?
                belong[x.l]<belong[y.l]:
                	(belong[x.l]&1)?
                	    x.r<y.r:x.r>y.r;
    }
    LL sum;
    inline void Inc(LL x){
        x=col[x];
        if(x)
            sum+=cnt[x],cnt[x]++;
    }
    inline void Del(LL x){
        x=col[x];
        if(x)
            cnt[x]--,
            sum-=cnt[x];
    }
    int main(){
        ch['y']=0,ch['u']=1,ch['z']=2,ch['s']=3,ch['o']=4,ch['f']=5,ch['t']=6;
        n=Read(),m=Read(),K=Read();
        scanf(" %s",s+1);
        Init();
        for(LL i=n,j=1;i>=1;--i,++j)
            Insert(ch[s[i]],j);
        Build();
        Dfs(n+1,(K==0));
        for(LL i=1;i<=(n/2);++i)
            swap(col[i],col[n-i+1]);
        for(LL i=1;i<=m;++i){
            LL l=Read(),r=Read();
            q[i]=(node){l,r,i};
        }
        size=ceil((double)n/sqrt(m));
        pieces=n/size;
        for(LL i=1;i<=pieces;++i)
            for(LL j=(i-1)*pieces+1;j<=i*pieces;++j)
                belong[j]=i;
        sort(q+1,q+1+m,cmp);
        LL l=1,r=0;
        for(LL i=1;i<=m;++i){
            LL ql=q[i].l,qr=q[i].r,x;
            while(l<ql)
                Del(l++);
            while(l>ql)
                Inc(--l);
            while(r<qr)
                Inc(++r);
            while(r>qr)
                Del(r--);
            ans[q[i].id]=sum;
        }
        for(LL i=1;i<=m;++i)
            printf("%lld
    ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    LruCache 原理
    线程间通信, 进程间通信
    安卓 权限 规则
    android 捕获所有异常 未捕获的异常
    serializable parcelable
    android intent 传递 二进制数据
    apk安装 卸载 原理
    ARGB 8888 内存大小
    dalvik 基于 jvm 的改进
    查看 MySQL 数据库中每个表占用的空间大小
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10201141.html
Copyright © 2011-2022 走看看