QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#857825#9921. YelkrabXia_uwuWA 1ms3584kbC++208.2kb2025-01-16 03:57:032025-01-16 03:57:11

Judging History

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

  • [2025-01-16 03:57:11]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3584kb
  • [2025-01-16 03:57:03]
  • 提交

answer

#include<bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using ld = long double;

/*
sum s = 1e6

n = 5e5

如何判断分支?

1e6 * 26 = 2e7,不会T

直接枚举26次
*/

struct trie {
    std::vector<std::array<int, 26>> next;
    std::vector<int> exist;
    std::vector<int> g;
    std::vector<std::multiset<int>> val;
    int cnt = 0;
    
    int time = 0;
    i64 ans = 0;
    trie(int size, int n) {//size大小应满足 :n <= sum(|s|)
        next.resize(size + 1);
        exist.resize(size + 1);
        g.resize(n + 1);
        val.resize(n + 1);
    }
    void insert(const std::string& s) {
        time++;
        int p = 0;
        for (int i = 0; i < s.size(); i++) {//dep实际上就是i + 1吧
            
            int c = s[i] - 'a';
            if (!next[p][c]) next[p][c] = ++cnt;
            
            p = next[p][c];
            
            exist[p]++;

            //std::cout << "^&*(^&*(^&*()))";
            for (int j = 1; j * j <= exist[p]; j++) {
                if (!(exist[p] % j)) {
                    // dep = (i + 1)
                    //判断要新增,还是只是替换
                    //和添加次数有关应该
                    //如果val[j].size() < time / j,那么可以新增
                    //反之则只是替换
                    if (val[j].size() < time / j) {//新增
                        ans ^= g[j] * j;

                        val[j].insert(i + 1);
                        g[j] += i + 1;

                        ans ^= g[j] * j;
                    } else {//只是替换最小的
                        ans ^= g[j] * j;
                        g[j] -= *val[j].begin();
                        val[j].extract(*val[j].begin());
                        val[j].insert(i + 1);
                        g[j] += i + 1;
                        ans ^= g[j] * j;
                    }
                    
                    //std::cout << "{" << j << "->" << g[j] << "}\n";

                    if (exist[p] / j != j) {
                        int j_ = exist[p] / j;
                        if (val[j_].size() < time / j_) {//新增
                            ans ^= g[j_] * j_;

                            val[j_].insert(i + 1);
                            g[j_] += i + 1;

                            ans ^= g[j_] * j_;
                            //std::cout << "!!";
                        } else {//只是替换最小的
                            ans ^= g[j_] * j_;
                            g[j_] -= *val[j_].begin();
                            val[j_].extract(*val[j_].begin());
                            val[j_].insert(i + 1);
                            g[j_] += i + 1;
                            ans ^= g[j_] * j_;
                            //std::cout << "??";
                        }
                        //std::cout << "{{" << j_ << "->" << g[j_] << "}}\n";
                    }

                    
                }
            }                  

            
        }

        // exist[p]++;

        // for (int j = 1; j * j <= exist[p]; j++) {
        //     if (!(exist[p] % j)) {
        //         // dep = (i + 1)
        //         //判断要新增,还是只是替换
        //         //和添加次数有关应该
        //         //如果val[j].size() < time / j,那么可以新增
        //         //反之则只是替换
        //         if (val[j].size() < time / j) {//新增
        //             ans ^= g[j] * j;

        //             val[j].insert(s.size());
        //             g[j] += s.size();

        //             ans ^= g[j] * j;
        //         } else {//只是替换最小的
        //             ans ^= g[j] * j;
        //             g[j] -= *val[j].begin();
        //             val[j].extract(*val[j].begin());
        //             val[j].insert(s.size());
        //             g[j] += s.size();
        //             ans ^= g[j] * j;
        //         }

        //         if (exist[p] / j != j) {
        //             int j_ = exist[p] / j;
        //             if (val[j_].size() < time / j_) {//新增
        //                 ans ^= g[j_] * j_;

        //                 val[j_].insert(s.size());
        //                 g[j_] += s.size();

        //                 ans ^= g[j_] * j_;
        //             } else {//只是替换最小的
        //                 ans ^= g[j_] * j_;
        //                 g[j_] -= *val[j_].begin();
        //                 val[j_].extract(*val[j_].begin());
        //                 val[j_].insert(s.size());
        //                 g[j_] += s.size();
        //                 ans ^= g[j_] * j_;
        //             }
        //         }
        //     }
        // }   
    }

    std::set<int> dfs_val;//存权值
    int dfs_g;
    void dfs(int now, int dep, int k) {// [可选] 先序遍历所有字符串(初始参数:0, 0)
        // if (exist[now]) {
        //     std::cout << t.substr(0, dep) << "\n";// [editable] 该字符串即为一次遍历结果,这里修改对其进行的操作
        // }

/*

                if (!(exist[p] % j)) {
                    // dep = (i + 1)
                    //判断要新增,还是只是替换
                    //和添加次数有关应该
                    //如果val[j].size() < time / j,那么可以新增
                    //反之则只是替换
                    if (val[j].size() < time / j) {//新增
                        ans ^= g[j] * j;

                        val[j].insert(i + 1);
                        g[j] += i + 1;

                        ans ^= g[j] * j;
                    } else {//只是替换最小的
                        ans ^= g[j] * j;
                        g[j] -= *val[j].begin();
                        val[j].extract(*val[j].begin());
                        val[j].insert(i + 1);
                        g[j] += i + 1;
                        ans ^= g[j] * j;
                    }

*/


        for (int j = 1; j <= exist[now]; j++) {
            if (!(exist[now] % j)) {
                if (dfs_val.size() < time / j) {
                    dfs_val.insert(dep);
                    dfs_g += dep;
                } else {
                    dfs_g -= *dfs_val.begin();
                    dfs_val.extract(*dfs_val.begin());
                    dfs_val.insert(dep);
                    dfs_g += dep;
                }
            }
        }

        for (int i = 0; i < 26; i++) {
            if (next[now][i]) {
                dfs(next[now][i], dep + 1, k);
                //t[dep] = 'a' + i;
                //sum += dfs(next[now][i], dep + 1, k) + exist[next[now][i]] / k * (dep + 1);
            }
        }
    }

    i64 f(int k) {
        dfs_val.clear();
        dfs_g = 0;

        dfs(0, 0, k);

        return dfs_g;
    }
};

/*
3 4 12 3 2 
15 
*/

void solve0() {
    int n;
    std::cin >> n;

    int len = 0;
    std::vector<std::string> a(n);
    for (auto &s : a) {
        std::cin >> s;
        len += s.size();
    }

    trie tr(len, n);

    //如何求f(i, j)

    for (int i = 1; i <= n; i++) {
        tr.insert(a[i - 1]);

        i64 ans = 0;
        std::cout << "[" << i << ": ";
        for (int j = 1; j <= i; j++) {
            std::cout << tr.f(j) << " ";
            ans ^= tr.f(j) * j;
        }
        std::cout << "]\n";

        std::cout << ans << " ";
    }

    std::cout << "\n";
}

/*
2 4 6 10 11 
5 
*/

void solve() {
    int n;
    std::cin >> n;

    int len = 0;
    std::vector<std::string> a(n);
    for (auto &s : a) {
        std::cin >> s;
        len += s.size();
    }

    trie tr(len, n);

    for (int i = 1; i <= n; i++) {
        tr.insert(a[i - 1]);

        // std::cout << "[" << i << ": ";
        // for (int j = 1; j <= i; j++) {
        //     std::cout << tr.g[j] << " ";
        // }
        // std::cout << "]\n";

        std::cout << tr.ans << " ";
    }
    std::cout << "\n";
}

signed main() {
    std::cin.tie(0) -> sync_with_stdio(false);
    int t = 1;
    std::cin >> t;
    while (t--) solve();
    return 0;
}

詳細信息

Test #1:

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

input:

2
5
aa
ab
ab
ac
d
1
aaaaa

output:

2 6 1 9 8 
5 

result:

ok 6 numbers

Test #2:

score: -100
Wrong Answer
time: 1ms
memory: 3584kb

input:

10
10
bba
bbaaaabbbaaabaabbbaaaaaababaababbb
b
baaabbaab
babbb
bbbbbaaaaababbabbabbb
bbaaaabbabb
b
aaaaabab
abbbabbabab
10
abb
ab
bbaaaba
bbabbabba
bbbabbbababaaaab
b
aaaa
babababbb
ab
a
2
aaaaabbaabbbbbababbbbbaabababbbaaababbbaaaaabbbaabaabababbaababbabbabbaababbbbbabbbabaaabbbabab
abbaaaaaaaabbaa...

output:

3 69 65 91 81 147 181 190 136 155 
3 1 22 21 74 73 76 90 108 98 
95 146 
32 38 39 47 54 170 166 161 204 255 
3 37 64 191 190 231 247 230 282 
40 53 62 63 
12 67 68 70 161 187 177 200 195 197 
10 69 72 88 140 
12 22 26 57 75 86 113 145 155 153 
50 

result:

wrong answer 2nd numbers differ - expected: '35', found: '69'