比赛 20241021 评测结果 AAAAAAAA
题目名称 大话西游 最终得分 100
用户昵称 健康铀 运行时间 0.422 s
代码语言 C++ 内存使用 6.81 MiB
提交时间 2024-10-21 11:20:06
显示代码纯文本
#include<bits/stdc++.h>
using namespace std; 
const int MAXN = 200010;  
int nodeCount, queryCount, num;   
int values[MAXN], subtreeSize[MAXN], nodeId[MAXN], depthFirstNumber[MAXN], parentNode[MAXN];  
struct Edge {  
    int destination;  
    int edgeIndex;  
    int nextEdge;  
};  
Edge edges[MAXN];  
int head[MAXN], totalEdges = 1;  
struct SegmentTreeNode {  
    int left, right;  
    int minValue, maxValue;  
};  
SegmentTreeNode segmentTree[MAXN << 2];  
char command[10];  
void readInt(int &x) {  
    register char c = getchar();  
    while (!isdigit(c)) c = getchar();  
    x = 0;  
    while (isdigit(c)) {  
        x = x * 10 + c - '0';  
        c = getchar();  
    }  
}  
void addEdge(int from, int to, int edgeIndex) {  
    edges[++totalEdges].destination = to;  
    edges[totalEdges].edgeIndex = edgeIndex;  
    edges[totalEdges].nextEdge = head[from];  
    head[from] = totalEdges;  
}  
int min(int a, int b) { return a < b ? a : b; }  
int max(int a, int b) { return a < b ? b : a; }  
void dfs(int currentNode, int parentNode) {  
    subtreeSize[currentNode] = 1;  
    depthFirstNumber[currentNode] = ++num;  
    nodeId[num] = currentNode;  

    for (int edgeIndex = head[currentNode]; edgeIndex; edgeIndex = edges[edgeIndex].nextEdge) {  
        int childNode = edges[edgeIndex].destination;  
        if (childNode == parentNode) continue;  
        ::parentNode[edges[edgeIndex].edgeIndex] = childNode;  
        dfs(childNode, currentNode);  
        subtreeSize[currentNode] += subtreeSize[childNode];  
    }  
}  
void buildSegmentTree(int node, int left, int right) {  
    segmentTree[node].left = left;  
    segmentTree[node].right = right;  

    if (left == right) {  
        segmentTree[node].minValue = segmentTree[node].maxValue = values[nodeId[left]];  
        return;  
    }  

    int mid = (left + right) >> 1;  
    buildSegmentTree(node << 1, left, mid);  
    buildSegmentTree(node << 1 | 1, mid + 1, right);  
    segmentTree[node].minValue = min(segmentTree[node << 1].minValue, segmentTree[node << 1 | 1].minValue);  
    segmentTree[node].maxValue = max(segmentTree[node << 1].maxValue, segmentTree[node << 1 | 1].maxValue);  
}  
void modifySegmentTree(int node, int index, int value) {  
    if (segmentTree[node].left == segmentTree[node].right) {  
        segmentTree[node].minValue = segmentTree[node].maxValue = value;  
        return;  
    }  

    int mid = (segmentTree[node].left + segmentTree[node].right) >> 1;  
    if (index <= mid) modifySegmentTree(node << 1, index, value);  
    else modifySegmentTree(node << 1 | 1, index, value);  

    segmentTree[node].minValue = min(segmentTree[node << 1].minValue, segmentTree[node << 1 | 1].minValue);  
    segmentTree[node].maxValue = max(segmentTree[node << 1].maxValue, segmentTree[node << 1 | 1].maxValue);  
}  
int queryMin(int node, int left, int right) {  
    if (left <= segmentTree[node].left && right >= segmentTree[node].right) return segmentTree[node].minValue;  

    int minValue = 1e9;  
    int mid = (segmentTree[node].left + segmentTree[node].right) >> 1;  
    
    if (left <= mid) minValue = min(minValue, queryMin(node << 1, left, right));  
    if (right > mid) minValue = min(minValue, queryMin(node << 1 | 1, left, right));  
    
    return minValue;  
}  
int queryMax(int node, int left, int right) {  
    if (left <= segmentTree[node].left && right >= segmentTree[node].right) return segmentTree[node].maxValue;  

    int maxValue = -1;  
    int mid = (segmentTree[node].left + segmentTree[node].right) >> 1;  
    
    if (left <= mid) maxValue = max(maxValue, queryMax(node << 1, left, right));  
    if (right > mid) maxValue = max(maxValue, queryMax(node << 1 | 1, left, right));  
    
    return maxValue;  
}  

int main() {  
	freopen("westward.in","r",stdin);
	freopen("westward.out","w",stdout);
    int x, y;  
    readInt(nodeCount);  
    readInt(queryCount);  
    for (int i = 1; i <= nodeCount; ++i) {  
        readInt(values[i]);  
    }  
    for (int i = 1; i < nodeCount; ++i) {  
        readInt(x);  
        readInt(y);  
        addEdge(x, y, i);  
        addEdge(y, x, i);  
    }  
    dfs(1, 0);    
    buildSegmentTree(1, 1, nodeCount);  
    for (int i = 1; i <= queryCount; ++i) {  
        scanf("%s", command);  
        if (command[0] == 'C') {  
            readInt(x);  
            readInt(y);  
            modifySegmentTree(1, depthFirstNumber[x], y);  
        } else {  
            readInt(x);  
            int left = depthFirstNumber[parentNode[x]], right = left + subtreeSize[parentNode[x]] - 1;  
            int min1 = queryMin(1, left, right), max1 = queryMax(1, left, right);  
            int min2 = 1e9, max2 = -1;  
            if (left > 1) min2 = queryMin(1, 1, left - 1), max2 = queryMax(1, 1, left - 1);  
            if (right < nodeCount) {  
                min2 = min(min2, queryMin(1, right + 1, nodeCount));  
                max2 = max(max2, queryMax(1, right + 1, nodeCount));  
            }  
            long long answer = (long long)min1 * (long long)max1 + (long long)min2 * (long long)max2;  
            printf("%lld\n", answer);  
        }  
    }   
    return 0;  
}