/ SeriousOJ /

Record Detail

Accepted


  
# Status Time Cost Memory Cost
#1 Accepted 37ms 43.27 MiB
#2 Accepted 147ms 43.52 MiB
#3 Accepted 96ms 43.27 MiB
#4 Accepted 147ms 43.312 MiB
#5 Accepted 163ms 43.52 MiB
#6 Accepted 167ms 44.312 MiB
#7 Accepted 247ms 50.062 MiB
#8 Accepted 250ms 50.062 MiB
#9 Accepted 252ms 50.062 MiB
#10 Accepted 265ms 50.02 MiB
#11 Accepted 248ms 50.02 MiB
#12 Accepted 251ms 50.246 MiB
#13 Accepted 76ms 54.43 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:37:06
Judged At
2024-08-24 23:37:06
Judged By
Score
100
Total Time
265ms
Peak Memory
54.43 MiB