QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#321478#7876. Cyclic SubstringsEndlineML 2ms16360kbC++203.1kb2024-02-04 20:22:102024-02-04 20:22:11

Judging History

你现在查看的是最新测评结果

  • [2024-02-04 20:22:11]
  • 评测
  • 测评结果:ML
  • 用时:2ms
  • 内存:16360kb
  • [2024-02-04 20:22:10]
  • 提交

answer

/*
 * Author: Endline
 * Time: 2024/02/04 17:25:18
 * File: String-N.cpp
 */
#include<bits/stdc++.h>
#define debug(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
using ll=long long;
const int MAXN=6000002;
const int mod=998244353;
template<typename _Tp>inline void Add(_Tp&x,ll y){x=x+y>=mod?x+y-mod:x+y;}
template<typename _Tp>inline void Mul(_Tp&x,ll y){x=x*y>=mod?x*y%mod:x*y;}
int n;
string str;
struct SegmentTree
{
    int pcnt;
    int tr[MAXN*10];
    int ls[MAXN*10],rs[MAXN*10];
    inline void pushup(int p)
    {
        tr[p]=tr[ls[p]]+tr[rs[p]];
    }
    void update(int goal,int s,int t,int&p,int k)
    {
        if(!p)p=++pcnt;
        if(s==t){tr[p]+=k;return;}
        int mid=s+t>>1;
        if(mid>=goal)update(goal,s,mid,ls[p],k);
        else update(goal,mid+1,t,rs[p],k);
        pushup(p);
    }
    void merge(int l,int r,int&p1,int p2)
    {
        if(!p2)return;
        if(!p1){p1=p2;return;}
        if(l==r){tr[p1]+=tr[p2];return;}
        int mid=l+r>>1;
        merge(l,mid,ls[p1],ls[p2]);
        merge(mid+1,r,rs[p1],rs[p2]);
        pushup(p1);
    }
    ll query(int l,int r,int s,int t,int p)
    {
        if(s>=l&&t<=r)return tr[p];
        int mid=s+t>>1;ll res=0;
        if(mid>=l)Add(res,query(l,r,s,mid,ls[p]));
        if(mid<r)Add(res,query(l,r,mid+1,t,rs[p]));
        return res;
    }
}tr;
struct PlalindromeAutomaton
{
    ll ans;
    string str;
    int pcnt=1,las,ecnt;
    int rt[MAXN];
    int ch[MAXN][10],fail[MAXN],len[MAXN],cnt[MAXN],val[MAXN],ed[MAXN],head[MAXN];
    struct TreeEdge
    {
        int v,nxt;
    }e[MAXN];
    inline void addedge(int u,int v)
    {
        e[++ecnt]={v,head[u]};
        head[u]=ecnt;
    }
    inline int getfail(int p,int id)
    {
        while(id-len[p]-1<1||str[id-len[p]-1]!=str[id])p=fail[p];
        return p;
    }
    inline void extend(int c,int id)
    {
        int p=getfail(las,id);
        if(!ch[p][c])
        {
            pcnt++;
            ed[pcnt]=id;
            fail[pcnt]=ch[getfail(fail[p],id)][c];
            len[pcnt]=len[p]+2;
            ch[p][c]=pcnt;
        }
        cnt[ch[p][c]]++;
        las=ch[p][c];
        return;
    }
    inline void insert(string s)
    {
        str=' '+s;
        for(int i=1;i<=s.size();i++)
            extend(str[i]-'0',i);
        return;
    }
    inline void init()
    {
        fail[0]=1,len[1]=-1;
    }
    void dfs(int u)
    {
        for(int i=head[u];i;i=e[i].nxt)
        {
            int v=e[i].v;
            dfs(v);
            tr.merge(1,n<<1,rt[u],rt[v]);
        }
        val[u]=tr.query(1,n+len[u]-1,1,n<<1,rt[u]);
    }
    inline ll work()
    {
        for(int i=2;i<=pcnt;i++)
            addedge(fail[i],i),tr.update(ed[i],1,n<<1,rt[i],1);
        dfs(0);
        for(int i=2;i<=pcnt;i++)
            if(len[i]<=n)Add(ans,1ll*val[i]*val[i]%mod*len[i]%mod);
        return ans;
    }
}Pt;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n;
    cin>>str;str=str+str;
    Pt.init();
    Pt.insert(str);
    printf("%lld\n",Pt.work());
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 2ms
memory: 16360kb

input:

5
01010

output:

39

result:

ok 1 number(s): "39"

Test #2:

score: 0
Accepted
time: 0ms
memory: 16336kb

input:

8
66776677

output:

192

result:

ok 1 number(s): "192"

Test #3:

score: -100
Memory Limit Exceeded

input:

1
1

output:


result: