码迷,mamicode.com
首页 > 其他好文 > 详细

2018焦作网络赛H

时间:2018-09-16 15:22:46      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:+=   one   names   name   分享图片   last   auto   sizeof   microsoft   

求一个串中出现次数在[L,R]区间里的子串一共有多少个,后缀数组用出现次数>=L的个数减去出现次数>R的个数就是答案。

 

 

 

 

技术分享图片
//#define test
#include<bits/stdc++.h>
using namespace std;
const int Nmax=250007;
const int Cmax=26;
typedef long long ll;
int n,a,b;
ll ans;
string s;
struct SuffixAutomaton
{
    int cnt,root,last;
    int next[Nmax*2],Max[Nmax*2],end_pos[Nmax*2],right[Nmax*2];
    int child[Nmax*2][Cmax];
    SuffixAutomaton() {
        cnt=0;
        root=last=newnode(0);
    }
    inline void clear()
    {
        ans=0LL;
        cnt=0;
        memset(next,0,sizeof(next));
        memset(Max,0,sizeof(Max));
        memset(end_pos,0,sizeof(end_pos));
        memset(right,0,sizeof(right));
        memset(child,0,sizeof(child));
        root=last=newnode(0);
    }
    int newnode(int val) {
        cnt++;
        next[cnt]=end_pos[cnt]=0;
        Max[cnt]=val;
        memset(child[cnt],0,sizeof(child[cnt]));
        return cnt;
    }
    void insert(int data,int a,int b) {
        int p=last,u=newnode(Max[last]+1);
        last=u;

        for(; p&&!child[p][data]; p=next[p])
            child[p][data]=u;

        if(!p)
            next[u]=root;
        else {
            int old=child[p][data];

            if(Max[old]==Max[p]+1)
                next[u]=old;
            else {
                int New=newnode(Max[p]+1);
                copy(child[old],child[old]+Cmax,child[New]);
                right[New]=right[old];
                next[New]=next[old];
                next[u]=next[old]=New;

                for(; child[p][data]==old; p=next[p])
                    child[p][data]=New;
            }
        }

        p=last;

        //while(p&&right[p]<b) {
        while(p&&right[p]<a) {
            right[p]++;

            if(right[p]==a)
            //if(right[p]>=a && right[p]<=b) 
                ans+=(ll)Max[p]-Max[next[p]];

            p=next[p];
        }
    }
    void build(string s,int a,int b) {
        int n=(int)s.length();
        ans=0LL;
        for(int i=0; i<n; i++)
            insert(s[i]-A,a,b);
    }
}sam;
int main()
{
    //freopen("H.in","r",stdin);
    ios::sync_with_stdio(false);

    while(cin>>s>>a>>b)
    {
        //cout<<s<<endl;
        //ll res=0;
        //for(int i=a;i<=b;i++)
        //{
            //sam.clear();
            //sam.build(s,i,b);
            //ll ans1=ans;
            //sam.clear();
            //sam.build(s,i+1,b);
            //ll ans2=ans;
            //res+=ans1-ans2;
        //}
        //sam.clear();
        //sam.build(s,a,b);

        
        //res+=ans;
        
        //sam.build(s,a,b);
        //cout<<res<<endl;
        //ll ans1=ans;
        sam.clear();
        sam.build(s,a,b);
        ll ans1=ans;
        sam.clear();
        sam.build(s,b+1,b);
        ll ans2=ans;
        cout<<ans1-ans2<<endl;
        //ll ans2=ans;
        //sam.clear();
        //sam.build(s,b,b);
        //ll ans3=ans;
        //cout<<ans1-ans2+ans3<<endl;

        //printf("%lld\n",ans);
        //printf("%d:%d\n",a,ans);
        //sam.clear();
        //sam.build(s,b+1);
        //printf("%d:%d\n",b+1,ans);
        //int ans2=ans;
        //cout<<ans1-ans2<<"\n";
    }
    return 0;
}
View Code

 

2018焦作网络赛H

标签:+=   one   names   name   分享图片   last   auto   sizeof   microsoft   

原文地址:https://www.cnblogs.com/LMissher/p/9655121.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!