QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#620350#7876. Cyclic SubstringswzxtslWA 84ms249860kbC++234.9kb2024-10-07 17:39:512024-10-07 17:39:51

Judging History

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

  • [2024-10-07 17:39:51]
  • 评测
  • 测评结果:WA
  • 用时:84ms
  • 内存:249860kb
  • [2024-10-07 17:39:51]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
// #define int long long
const int mod= 998244353;
long long sum=0;
int lens=0;
int cnc=0;
int nl[6000002]={0};
int nc[6000002]={0};
//int bronya=0;
struct Node {
    int len;                  // 节点表示的回文子串的长度
    int link;                 // 后缀链接
   // map<char, int> next; // 从当前节点转移到的节点
    int next[11];
    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[letter-'0']) {
        last = nodes[p].next[letter-'0'];
  
        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-'0'] = 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-'0'];
}

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[letter-'0']) {
        last1 = nodes1[p].next[letter-'0'];
        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-'0'] = 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-'0'];
}

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 <cnc; ++i) {
    //   cout<< nodes[i].cnt<<" "<<nodes1[i].cnt<<endl;
      //nodes[i].len <= lens&&nodes[i].start_idx <= lens&&
        if (nl[i]<=lens&&i<nodes1.size()) {
            sum=(sum%mod+nl[i]%mod*(nc[i]-nodes1[i].cnt)%mod*(nc[i]-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(nl[i]<=lens){
            sum=(sum%mod+nl[i]%mod*(nc[i])%mod*(nc[i])%mod)%mod;
         //   cout << "Length1: " << nodes[i].len << ", Count1: " << nodes[i].cnt <<  endl;
        }
    }
    cout<<sum<<endl;
}


int  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);
    }
    count_all();
    cnc=nodes.size();
    for(int i=2;i<nodes.size();i++){
       nl[i]=nodes[i].len;
       nc[i]=nodes[i].cnt;
    } 
    nodes.clear();
    init1(lens);
    for (char c : s_input) {
        add_letter1(c);
    }
    count_all1();
    get_palindromes();
  
   nodes1.clear();
    return 0;
}
//aba  abaaba
//abb  abbabb
//01010 0101001010

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 5596kb

input:

5
01010

output:

39

result:

ok 1 number(s): "39"

Test #2:

score: 0
Accepted
time: 1ms
memory: 5600kb

input:

8
66776677

output:

192

result:

ok 1 number(s): "192"

Test #3:

score: 0
Accepted
time: 1ms
memory: 5600kb

input:

1
1

output:

1

result:

ok 1 number(s): "1"

Test #4:

score: 0
Accepted
time: 1ms
memory: 5824kb

input:

2
22

output:

12

result:

ok 1 number(s): "12"

Test #5:

score: 0
Accepted
time: 1ms
memory: 5536kb

input:

2
21

output:

2

result:

ok 1 number(s): "2"

Test #6:

score: 0
Accepted
time: 1ms
memory: 5664kb

input:

3
233

output:

10

result:

ok 1 number(s): "10"

Test #7:

score: 0
Accepted
time: 1ms
memory: 5660kb

input:

3
666

output:

54

result:

ok 1 number(s): "54"

Test #8:

score: -100
Wrong Answer
time: 84ms
memory: 249860kb

input:

1000000
3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333...

output:

-326878921

result:

wrong answer 1st numbers differ - expected: '496166704', found: '-326878921'