/ SeriousOJ /

Record Detail

Accepted


  
# Status Time Cost Memory Cost
#1 Accepted 17ms 46.27 MiB
#2 Accepted 133ms 45.52 MiB
#3 Accepted 80ms 44.945 MiB
#4 Accepted 116ms 46.734 MiB
#5 Accepted 130ms 43.773 MiB
#6 Accepted 157ms 47.562 MiB
#7 Accepted 249ms 50.445 MiB
#8 Accepted 245ms 50.238 MiB
#9 Accepted 251ms 50.27 MiB
#10 Accepted 245ms 50.293 MiB
#11 Accepted 251ms 50.27 MiB
#12 Accepted 262ms 50.27 MiB
#13 Accepted 55ms 50.77 MiB

Code

#include <bits/stdc++.h>
using namespace std;

#define SC               scanf
#define PF               printf
#define ull              unsigned long long
#define ld               long double
#define D                double
#define F                first
#define S                second
#define pb               push_back
#define sort_a(a)        sort(a.begin(),a.end());
#define sort_d(a)        sort(a.rbegin(),a.rend());
#define READ(f)          freopen(f, "r", stdin)
#define WRITE(f)         freopen(f, "w", stdout)
#define rev(s)           reverse(s.begin(),s.end())
#define __Heart__        ios_base::sync_with_stdio(false); cin.tie(NULL);
#define ll long long
typedef pair<int,int> PII;
const int MX = 1e5 + 5;
const int szAlph = 26;

int n, q, arr[MX], discovery_time[MX], finishing_time[MX], Time = 0;
char a[MX];
vector<int> Edge[MX];

int charToIndex(char c) {
    return c - 'a';
}

char indexToChar(int index) {
    return 'a' + index;
}

//void DFS(int id, int par) {
//    discovery_time[id] = ++Time;
//    arr[Time] = charToIndex(a[id]);
//    for (int child : Edge[id]) {
//        if (child == par) continue;
//        DFS(child, id);
//    }
//    finishing_time[id] = Time;
//}

void DFS(int id, int par) {
    stack<pair<int, int>> st;
    st.push({id, par});
    vector<bool> is_vis (n + 1, false);

    while (!st.empty()) {
        auto it = st.top();

        if (!is_vis[it.F]) {
            is_vis[it.F] = true;
            discovery_time[it.F] = ++Time;
            arr[Time] = charToIndex(a[it.F]);
            for (int child : Edge[it.F]) {
                if (child != it.S) {
                    st.push({child, it.F});
                }
            }
        } else {
            finishing_time[it.F] = Time;
            st.pop();
        }
    }
}

struct SegmentTreeNode {
    int maxFreq;
    int minValWithMaxFreq;
    int freqCount[szAlph];

    SegmentTreeNode() : maxFreq(0), minValWithMaxFreq(INT_MAX) {
        fill(freqCount, freqCount + szAlph, 0);
    }

    void merge(const SegmentTreeNode& left, const SegmentTreeNode& right) {
        maxFreq = 0;
        minValWithMaxFreq = INT_MAX;
        fill(freqCount, freqCount + szAlph, 0);

        for (int i = 0; i < szAlph; ++i) {
            freqCount[i] = left.freqCount[i] + right.freqCount[i];
            if (freqCount[i] > maxFreq) {
                maxFreq = freqCount[i];
                minValWithMaxFreq = i;
            } else if (freqCount[i] == maxFreq) {
                minValWithMaxFreq = min(minValWithMaxFreq, i);
            }
        }
    }
};

SegmentTreeNode tree[MX * 4];

void init(int node, int b, int e) {
    if (b == e) {
        tree[node].freqCount[arr[b]] = 1;
        tree[node].maxFreq = 1;
        tree[node].minValWithMaxFreq = arr[b];
        return;
    }
    int mid = (b + e) / 2;
    int left = node * 2;
    int right = node * 2 + 1;
    init(left, b, mid);
    init(right, mid + 1, e);
    tree[node].merge(tree[left], tree[right]);
}

SegmentTreeNode query(int node, int b, int e, int i, int j) {
    if (i > e || j < b) {
        return SegmentTreeNode();
    }
    if (b >= i && e <= j) {
        return tree[node];
    }
    int mid = (b + e) / 2;
    int left = node * 2;
    int right = node * 2 + 1;
    SegmentTreeNode leftResult = query(left, b, mid, i, j);
    SegmentTreeNode rightResult = query(right, mid + 1, e, i, j);

    SegmentTreeNode result;
    result.merge(leftResult, rightResult);
    return result;
}

void update(int node, int b, int e, int pos, int oldValue, int newValue) {
    if (pos > e || pos < b) return;

    if (b == e) {
        if (oldValue != newValue) {
            tree[node].freqCount[oldValue]--;
            if (tree[node].freqCount[oldValue] == 0) {
                tree[node].freqCount[oldValue] = 0;
            }
            tree[node].freqCount[newValue]++;
            tree[node].maxFreq = tree[node].freqCount[newValue];
            tree[node].minValWithMaxFreq = newValue;
        }
        return;
    }

    int mid = (b + e) / 2;
    int left = node * 2;
    int right = node * 2 + 1;

    if (pos <= mid) {
        update(left, b, mid, pos, oldValue, newValue);
    } else {
        update(right, mid + 1, e, pos, oldValue, newValue);
    }
    tree[node].merge(tree[left], tree[right]);
}

void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        Edge[u].push_back(v);
        Edge[v].push_back(u);
    }

    DFS(1, -1);
    cin >> q;
    init(1, 1, n);

    for (int i = 0; i < q; i++) {
        int ty, node;
        cin >> ty >> node;
        int l = discovery_time[node];
        int r = finishing_time[node];
        if (ty == 1) {
            char newChar;
            cin >> newChar;
            int val = charToIndex(newChar);
            int oldValue = arr[l];
            update(1, 1, n, l, oldValue, val);
            arr[l] = val;
        } else {
            cout << indexToChar(query(1, 1, n, l, r).minValWithMaxFreq) << "\n";

        }
    }
}

int main() {
    __Heart__
     //READ("input12.txt");
     //WRITE("output12.txt") ;
    int t = 1; while (t--) solve();
}

Information

Submit By
Type
Submission
Problem
P1091 Alphabetical Kingdom
Language
C++20 (G++ 13.2.0)
Submit At
2024-08-24 23:32:27
Judged At
2024-08-24 23:32:27
Judged By
Score
100
Total Time
262ms
Peak Memory
50.77 MiB