QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#620199#7876. Cyclic Substringswzxtsl#ML 240ms409552kbC++234.7kb2024-10-07 16:58:432024-10-07 16:59:15

Judging History

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

  • [2024-10-07 16:59:15]
  • 评测
  • 测评结果:ML
  • 用时:240ms
  • 内存:409552kb
  • [2024-10-07 16:58:43]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod= 998244353;
int sum=0;
int lens=0;
//int bronya=0;
struct Node {
    int len;                  // 节点表示的回文子串的长度
    int link;                 // 后缀链接
     map<char, int> next; // 从当前节点转移到的节点
    int cnt;   
             // 回文子串出现次数
};

vector<Node> nodes;      // 节点数组
int last;                     // 上一个字符结束的最大回文子串节点
 string s;                // 构建中的字符串
int k;                        // 限制的最大回文子串长度
 vector<Node> nodes1;
int last1;  
 string s1;                // 构建中的字符串
int k1;     
void init(int max_len) {
    nodes.push_back({-1, 0, {}, 0}); // root for odd lengths
    nodes.push_back({ 0, 0, {}, 0}); // root for even lengths
    last = 1;
    s.push_back(-1); // -1 是一个虚拟字符,保证边界条件处理
    k = max_len;
}
void init1(int max_len) {
    nodes1.push_back({-1, 0, {}, 0}); // root for odd lengths
    nodes1.push_back({ 0, 0, {}, 0}); // root for even lengths
    last1 = 1;
    s1.push_back(-1); // -1 是一个虚拟字符,保证边界条件处理
    k1 = max_len;
}

void add_letter(char letter) {
    //bronya++;
    s.push_back(letter);
    int cur = s.size() - 1;

    int p = last;
    while (s[cur - nodes[p].len - 1] != letter) {
        p = nodes[p].link;
    }
    
 
    if (nodes[p].next.count(letter)) {
        last = nodes[p].next[letter];
  
        nodes[last].cnt++;
        return;
    }
    int new_len = nodes[p].len + 2;

    last = nodes.size();
    if (new_len > k ) {
        last = p; // 更新 last 为当前节点
        return;   // 不添加超过限制的新节点
    }
    nodes.push_back({ new_len, 0, {}, 1});
    nodes[p].next[letter] = last;

    if (nodes[last].len == 1) {
        nodes[last].link = 1;
        return;
    }

    p = nodes[p].link;
    while (s[cur - nodes[p].len - 1] != letter) {
        p = nodes[p].link;
    }

    nodes[last].link = nodes[p].next[letter];
}

void add_letter1(char letter) {
    //bronya++;
    s1.push_back(letter);
    int cur = s1.size() - 1;

    int p = last1;
    while (s[cur - nodes1[p].len - 1] != letter) {
        p = nodes1[p].link;
    }
    
    //cout<<start_idx<<endl;
    if (nodes1[p].next.count(letter)) {
        last1 = nodes1[p].next[letter];
        nodes1[last1].cnt++;
        return;
    }
    int new_len = nodes1[p].len + 2;


    last1 = nodes1.size();
    if (new_len > k1 ) {
        last1 = p; // 更新 last 为当前节点
        return;   // 不添加超过限制的新节点
    }
    nodes1.push_back({ new_len, 0, {}, 1, });
    nodes1[p].next[letter] = last1;

    if (nodes1[last1].len == 1) {
        nodes1[last1].link = 1;
        return;
    }

    p = nodes1[p].link;
    while (s[cur - nodes1[p].len - 1] != letter) {
        p = nodes1[p].link;
    }

    nodes1[last1].link = nodes1[p].next[letter];
}

void count_all() {
    // 从后向前累加每个回文子串的出现次数到其后缀链接
    for (int i = nodes.size() - 1; i >= 2; --i) {
        nodes[nodes[i].link].cnt += nodes[i].cnt;
    }
}
void count_all1() {
    // 从后向前累加每个回文子串的出现次数到其后缀链接
    for (int i = nodes1.size() - 1; i >= 2; --i) {
        nodes1[nodes1[i].link].cnt += nodes1[i].cnt;
    }
}

void get_palindromes() {
    for (int i = 2; i < nodes.size(); ++i) {
    //   cout<< nodes[i].cnt<<" "<<nodes1[i].cnt<<endl;
      //nodes[i].len <= lens&&nodes[i].start_idx <= lens&&
        if (nodes[i].len<=lens&&i<nodes1.size()) {
            sum=(sum%mod+nodes[i].len%mod*(nodes[i].cnt-nodes1[i].cnt)%mod*(nodes[i].cnt-nodes1[i].cnt)%mod)%mod;
         //   cout << "Length: " << nodes[i].len << ", Count: " << nodes[i].cnt <<  endl;
        }
        //if (nodes[i].len <= lens&&nodes[i].start_idx <= lens) 
        else if(nodes[i].len<=lens){
            sum=(sum%mod+nodes[i].len%mod*(nodes[i].cnt)%mod*(nodes[i].cnt)%mod)%mod;
         //   cout << "Length1: " << nodes[i].len << ", Count1: " << nodes[i].cnt <<  endl;
        }
    }
    cout<<sum<<endl;
}


signed main() {
   // k=5;
    int n;
    cin>>n;
    string s_input ;cin>>s_input;
    string splus=s_input+s_input;
    int max_length = n+n;
    lens=n;
    init(max_length);
    for (char c : splus) {
        add_letter(c);
    }
    init1(lens);
    for (char c : s_input) {
        add_letter1(c);
    }
    count_all();
    count_all1();
    get_palindromes();
  
    return 0;
}
//aba  abaaba
//abb  abbabb
//01010 0101001010

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3600kb

input:

5
01010

output:

39

result:

ok 1 number(s): "39"

Test #2:

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

input:

8
66776677

output:

192

result:

ok 1 number(s): "192"

Test #3:

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

input:

1
1

output:

1

result:

ok 1 number(s): "1"

Test #4:

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

input:

2
22

output:

12

result:

ok 1 number(s): "12"

Test #5:

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

input:

2
21

output:

2

result:

ok 1 number(s): "2"

Test #6:

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

input:

3
233

output:

10

result:

ok 1 number(s): "10"

Test #7:

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

input:

3
666

output:

54

result:

ok 1 number(s): "54"

Test #8:

score: 0
Accepted
time: 240ms
memory: 409552kb

input:

1000000
3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333...

output:

496166704

result:

ok 1 number(s): "496166704"

Test #9:

score: -100
Memory Limit Exceeded

input:

3000000
2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222...

output:

890701718

result: