CF1149C Tree Generator™——Ordinary line segment tree

topic

Portal

answer

There are two steps to solve this problem:

The first step is to transform the problem. In the title, the definition of the bracket tree is explained in detail (it is the English language above the picture) , so I don’t need to add this;

Since the diameter of the tree is defined as the longest path on the tree, that is, the distance between the two points furthest away, think about the distance between the two points in the bracket tree, we find that it is the number of remaining brackets between the two points (That is, remove the brackets that match successfully). If you don't believe me, you can take a look at the sample. Why? Because the bracket sequence is actually Euler's order ;

Now we require the distance between the two furthest points, that is, to find the maximum value S of the number of remaining brackets in the interval formed by all pairs of points on the bracket sequence. Except for the interval formed by point pairs, the number of remaining brackets in other intervals is impossible. More than S, so we finally transformed the problem into: With modification, find the maximum value of the number of remaining brackets in all intervals, the obvious line segment tree.

The second step is to consider how to write. Because the largest remaining bracket sequence in an interval on the line segment tree is either in the left interval, or in the right interval, or covers each part of the left and right sides, each node must maintain the information of the maximum value, prefix, suffix, etc., and then due to the remaining brackets The sequence must be several consecutive right parentheses and several consecutive left parentheses, so the prefix right parenthesis and suffix left parenthesis of each answer must be maintained. In order to assist in the calculation, the remaining parenthesis sequence prefix and suffix of the interval must be maintained.. .... So in the end I wrote such a merge operation (only the merge part):

(then)

。。

。。。

Finally, it confirmed the lyrics: "Two hundred lines of 10kb code, where is the error after running~"

Is there a better way to write it? Have!

When you combine the two remaining parenthesis sequences, set the number of right parentheses of the previous one to a, the number of left parentheses to b, the number of right parentheses of the next one to c, and the number of left parentheses to d. The length of the combined sequence is a+abs(c-b)+d=max(a+b+d-c,a-b+d+c), this When I disassembled max, I found that each interval only needs to maintain the suffix right parenthesis a+ suffix left parenthesis b, suffix right parenthesis a- suffix left parenthesis b, prefix left parenthesis d+ prefix right parenthesis c, prefix left parenthesis d- prefix right parenthesis c The maximum value of these 4 quantities and the answer are enough;

To maintain these 4 values, you need to use two auxiliary ones, the right parenthesis and the left parenthesis numbers e and f of the remaining parentheses sequence formed by the entire interval. Obviously, we can manually formulate the following formula:

//"ab"即a+b,"a_b"即a-b
t[x].ab=max(t[x<<1|1].ab,max(t[x<<1].ab-t[x<<1|1].e+t[x<<1|1].f,t[x<<1].a_b+t[x<<1|1].e+t[x<<1|1].f));
t[x].a_b=max(t[x<<1|1].a_b,t[x<<1].a_b+t[x<<1|1].e-t[x<<1|1].f);

In other words, a+b and ab do not need to be maintained by recording the values ​​of a and b (and the correctness cannot be guaranteed by simply maintaining the values ​​of a and b). The same goes for d+c and dc.

So you can get the following refreshing merge operation:

inline void docnt(int x){
	t[x].ab=max(t[x<<1|1].ab,max(t[x<<1].ab-t[x<<1|1].e+t[x<<1|1].f,t[x<<1].a_b+t[x<<1|1].e+t[x<<1|1].f));
	t[x].a_b=max(t[x<<1|1].a_b,t[x<<1].a_b+t[x<<1|1].e-t[x<<1|1].f);
	t[x].dc=max(t[x<<1].dc,max(t[x<<1|1].dc-t[x<<1].f+t[x<<1].e,t[x<<1|1].d_c+t[x<<1].f+t[x<<1].e));
	t[x].d_c=max(t[x<<1].d_c,t[x<<1|1].d_c+t[x<<1].f-t[x<<1].e);
	t[x].s=max(t[x<<1].ab+t[x<<1|1].d_c,t[x<<1].a_b+t[x<<1|1].dc);
	t[x].s=max(t[x].s,max(t[x<<1].s,t[x<<1|1].s));
	t[x].e=t[x<<1].e+max(0,t[x<<1|1].e-t[x<<1].f);
	t[x].f=t[x<<1|1].f+max(0,t[x<<1].f-t[x<<1|1].e);
}

The rest is the ordinary line segment tree. .

Code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
#define MAXN 200005
using namespace std;
inline ll read(){
	ll x=0;bool f=1;char s=getchar();
	while((s<'0'||s>'9')&&s>0){if(s=='-')f^=1;s=getchar();}
	while(s>='0'&&s<='9')x=(x<<1)+(x<<3)+s-'0',s=getchar();
	return f?x:-x;
}
int n,m,R;
struct itn{
	int ab,a_b,dc,d_c,s,e,f;
}t[MAXN<<2];
char s[MAXN];
inline void docnt(int x){
	t[x].ab=max(t[x<<1|1].ab,max(t[x<<1].ab-t[x<<1|1].e+t[x<<1|1].f,t[x<<1].a_b+t[x<<1|1].e+t[x<<1|1].f));
	t[x].a_b=max(t[x<<1|1].a_b,t[x<<1].a_b+t[x<<1|1].e-t[x<<1|1].f);
	t[x].dc=max(t[x<<1].dc,max(t[x<<1|1].dc-t[x<<1].f+t[x<<1].e,t[x<<1|1].d_c+t[x<<1].f+t[x<<1].e));
	t[x].d_c=max(t[x<<1].d_c,t[x<<1|1].d_c+t[x<<1].f-t[x<<1].e);
	
	t[x].s=max(t[x<<1].ab+t[x<<1|1].d_c,t[x<<1].a_b+t[x<<1|1].dc);
	t[x].s=max(t[x].s,max(t[x<<1].s,t[x<<1|1].s));
	
	t[x].e=t[x<<1].e+max(0,t[x<<1|1].e-t[x<<1].f);
	t[x].f=t[x<<1|1].f+max(0,t[x<<1].f-t[x<<1|1].e);
}
inline void build(int x,int l,int r){
	if(l==r){
		if(s[l]=='(')t[x].ab=t[x].dc=1,t[x].a_b=0,t[x].d_c=1,t[x].e=0,t[x].f=1;
		else t[x].ab=t[x].dc=1,t[x].a_b=1,t[x].d_c=0,t[x].e=1,t[x].f=0;
		t[x].s=1;
		return;
	}
	int mid=(l+r)>>1;
	build(x<<1,l,mid),build(x<<1|1,mid+1,r);
	docnt(x);
}
inline void change(int x,int l,int r,int z){
	if(l==r){
		if(s[l]=='(')t[x].ab=t[x].dc=1,t[x].a_b=0,t[x].d_c=1,t[x].e=0,t[x].f=1;
		else t[x].ab=t[x].dc=1,t[x].a_b=1,t[x].d_c=0,t[x].e=1,t[x].f=0;
		t[x].s=1;
		return;
	}
	int mid=(l+r)>>1;
	if(z<=mid)change(x<<1,l,mid,z);
	else change(x<<1|1,mid+1,r,z);
	docnt(x);
}
int main()
{
	n=read(),m=read(),R=(n-1)<<1;
	scanf("%s",s+1);
	build(1,1,R);
	printf("%d\n",t[1].s);
	for(int i=1;i<=m;i++){
		int u=read(),v=read();
		swap(s[u],s[v]),change(1,1,R,u),change(1,1,R,v);
		printf("%d\n",t[1].s);
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_43960287/article/details/112122210