Problem Solution

1 solutions

  • 0
    @ 2024-09-05 21:23:22
    #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;
    }
    
    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("input15.txt");
         //WRITE("output15.txt") ;
        int t = 1; while (t--) solve();
    }
    
    
  • 1

Information

ID
1091
Difficulty
5
Category
DP | BFS , Shortest_Path , Data_Structure | Segment_Tree , Binary_Indexed_Tree , Sparse_Table Click to Show
Tags
# Submissions
74
Accepted
28
Accepted Ratio
38%
Uploaded By