QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#620168#7876. Cyclic Substringswzxtsl#RE 0ms0kbC++234.9kb2024-10-07 16:52:192024-10-07 16:52:22

Judging History

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

  • [2024-10-07 16:52:22]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-10-07 16:52:19]
  • 提交

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;                 // 后缀链接
    std::map<char, int> next; // 从当前节点转移到的节点
    int cnt;   
    int start_idx;               // 回文子串出现次数
};

std::vector<Node> nodes;      // 节点数组
int last;                     // 上一个字符结束的最大回文子串节点
std::string s;                // 构建中的字符串
int k;                        // 限制的最大回文子串长度
std::vector<Node> nodes1;
int last1;  
std::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;
    int start_idx = cur - new_len + 1;

    // if (new_len > k || start_idx > lens ) {
    //     last = p; // 更新 last 为当前节点
    //     return;   // 不添加超过限制的新节点
    // }

    last = nodes.size();
    nodes.push_back({ new_len, 0, {}, 1, start_idx });
    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;
    int start_idx = cur - new_len + 1;
    // if (new_len > k1 || start_idx > lens ) {
    //     last1 = p; // 更新 last1 为当前节点
    //     return;   // 不添加超过限制的新节点
    // }

    last1 = nodes1.size();
    nodes1.push_back({ new_len, 0, {}, 1, start_idx });
    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;
         //  std::cout << "Length: " << nodes[i].len << ", Count: " << nodes[i].cnt << std::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;
         //  std::cout << "Length1: " << nodes[i].len << ", Count1: " << nodes[i].cnt << std::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();
    system("pause");
    return 0;
}
//aba  abaaba
//abb  abbabb
//01010 0101001010

詳細信息

Test #1:

score: 0
Dangerous Syscalls

input:

5
01010

output:

39

result: