Codeforces Round #556 (Div. 2) E. Tree Generator™(선분 수 교 인간 시리즈)
25882 단어 데이터 구조-선분 트 리
제목: 현재 괄호 서열 이 있 습 니 다. 괄호 서열 은 먼저 순서대로 옮 겨 다 니 는 나무 구 조 를 표현 합 니 다. 왼쪽 괄호 는 현재 노드 에서 아래로 옮 겨 다 니 는 것 을 나타 내 고 오른쪽 괄호 는 위로 거 슬러 올 라 가 는 것 을 나타 냅 니 다.m m 개의 조작 이 있 고 매번 조작 할 때마다 두 개의 괄호 의 위 치 를 교환 하 며 교환 한 후에 괄호 의 일치 가 똑 같이 합 리 적 임 을 보증 합 니 다.현재 괄호 시퀀스 에 표 시 된 트 리 직경 을 출력 해 야 합 니 다.
문제 풀이 소감:
codeforces 원생 의 문제 풀이:https://codeforces.com/blog/entry/66783
#include
using namespace std;
const int maxn = 2e5+100;
struct Node {
int depth, Min_depth, Max_depth, Max_lv, Max_rv, Max_lrv;
}node[maxn<<2];
int n, m;
char parenthesis[maxn];
void init() {
scanf("%d%d%s", &n, &m, parenthesis+1);
}
Node get_left_parenthesis() {
return Node{1, 0, 1, 0, 1, 1};
}
Node get_right_parenthesis() {
return Node{-1, -1, 0, 2, 1, 1};
}
Node shifted_left(int depth, int root) {
return Node{node[root].depth + depth, node[root].Min_depth+depth, node[root].Max_depth+depth,
node[root].Max_lv-depth, node[root].Max_rv-depth, node[root].Max_lrv};
}
void merge(int root) {
int chl = root<<1;
int chr = root<<1|1;
Node rhs_shifted = shifted_left(node[chl].depth, chr);
node[root].depth = rhs_shifted.depth;
node[root].Min_depth = min(node[chl].Min_depth, rhs_shifted.Min_depth);
node[root].Max_depth = max(node[chl].Max_depth, rhs_shifted.Max_depth);
node[root].Max_lv = max(node[chl].Max_lv, max(rhs_shifted.Max_lv, node[chl].Max_depth - 2*rhs_shifted.Min_depth));
node[root].Max_rv = max(node[chl].Max_rv, max(rhs_shifted.Max_rv, rhs_shifted.Max_depth - 2*node[chl].Min_depth));
node[root].Max_lrv = max(max(node[chl].Max_lrv, rhs_shifted.Max_lrv), max(node[chl].Max_lv + rhs_shifted.Max_depth,
rhs_shifted.Max_rv + node[chl].Max_depth));
}
void build_tree(int root, int l, int r) {
if(l == r) {
if(parenthesis[l] == '(') node[root] = get_left_parenthesis();
else node[root] = get_right_parenthesis();
return ;
}
int mid = l + r >> 1;
build_tree(root<<1, l, mid);
build_tree(root<<1|1, mid+1, r);
merge(root);
}
int query_max() {
return node[1].Max_lrv;
}
void change(int root, int l, int r, int find_pos, int change_pos) {
if(l == r) {
if(parenthesis[change_pos] == '(') node[root] = get_left_parenthesis();
else node[root] = get_right_parenthesis();
return ;
}
int mid = l + r >> 1;
if(find_pos <= mid) {
change(root<<1, l, mid, find_pos, change_pos);
} else {
change(root<<1|1, mid+1, r, find_pos, change_pos);
}
merge(root);
}
void change(int pos1, int pos2) {
change(1, 1, 2*n-2, pos1, pos2);
change(1, 1, 2*n-2, pos2, pos1);
}
int main() {
// freopen("1.in", "r", stdin);
init();
build_tree(1, 1, 2*n-2);
printf("%d
", query_max());
while(m--) {
int pos1, pos2; scanf("%d%d",&pos1, &pos2);
change(pos1, pos2);
swap(parenthesis[pos1], parenthesis[pos2]);
printf("%d
", query_max());
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Query on a string (선분 수) (2017 - icpc - 우루무치 온라인 경기)The operation C i chC~i~chC i ch with given integer iii and capital letter chchch, changes the iii-th character of SSS i...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.