Huake OJ-2020.08.22 Test Competition-Word Reading-Line Segment Tree Solution

Title description

  Huake OJ-2020.08.22 test match-word reading (requires Huake VPN) to
  find the word with the largest lexicographical order in the interval.

enter

  An integer N (1 ≤ N ≤ 1 0 6) N(1\leq N\leq10^6)N(1N106 );
  NextNNN lines, one word per line, the word length will not exceed 10, and only contain lowercase English letters; the
  next line has an integerM (1 ≤ M ≤ 1 0 6) M(1\leq M\leq 10^6)M(1M106 )Indicates the number of inquiries;
  nextMMM lines, two integersai, bi (1 ≤ ai ≤ bi ≤ N) a_i,b_i(1\leq a_i\leq b_i\leq N)ai,bi(1aibiN ) , separated by spaces.

Output

   M M M lines, each line is based onai, bi a_i, b_iaibi, Output from ai a_iaiTo bi b_ibiAmong the words, the word with the largest lexicographical order.

Problem solving ideas

Direct thinking

  Use the line segment tree to solve the problem of the maximum value of the interval. Direct construction: Except for the leaf nodes, the other node values ​​are the line segment trees with the maximum value of the child nodes.

#include <bits/stdc++.h>
using namespace std;

const int MAX = 1000005;
int N, M;
string words[MAX], tree[4 * MAX];

inline string str_max(string a, string b){
    
    
	if(a > b) return a;
	else return b;
}

inline void build(int node, int left, int right){
    
    
	if(left == right){
    
    
		tree[node] = words[left];
		return;
	}
	int mid = (left + right) >> 1;
	build(node << 1, left, mid);
	build(node << 1 | 1, mid + 1, right);
	tree[node] = str_max(tree[node << 1], tree[node << 1 | 1]);
	return;
} 

inline string query(int node, int left, int right, int ql, int qr){
    
    
	if(ql <= left && qr >= right) return tree[node];
	string res;
	int mid = (left + right) >> 1;
	if(ql <= mid) res = str_max(res, query(node << 1, left, mid, ql, qr));
	if(mid < qr) res = str_max(res, query(node << 1 | 1, mid + 1, right, ql, qr));
	return res;
}

int main(){
    
    
	
	scanf("%d", &N);
	char buf[20];
	for(int i = 1; i <= N; i++){
    
    
		scanf("%s", buf);
		words[i] = string(buf);
		//cin >> words[i];
	}
	build(1, 1, N);
	scanf("%d", &M);
	int l, r;
	for(int i = 1; i <= M; i++){
    
    
		scanf("%d%d", &l, &r);
		printf("%s\n", query(1, 1, N, l, r).c_str());
		//cout << query(1, 1, N, l, r) << "\n";
	}
	
	return 0;
}

optimization

  Because the nodes of the line segment tree constructed in the above way store string type data, there are a lot of string type replication problems during the construction process, and the string type replication is more complicated, which leads to the last two test points TLE. Change
  the storage type of the line segment tree node to store string*the address information of the corresponding string will greatly reduce the time and space overhead (about 50%); at the same time, modify the corresponding str_max() function for maximum value.

#include <bits/stdc++.h>
using namespace std;

const int MAX = 1000005;
int N, M;
string words[MAX], *tree[4 * MAX], init;

inline string* str_max(string *a, string *b){
    
    
	if(*a > *b) return a;
	else return b;
}

void build(int node, int left, int right){
    
    
	if(left == right){
    
    
		tree[node] = &words[left];
		return;
	}
	int mid = (left + right) >> 1;
	build(node << 1, left, mid);
	build(node << 1 | 1, mid + 1, right);
	tree[node] = str_max(tree[node << 1], tree[node << 1 | 1]);
	return;
} 

string* query(int node, int left, int right, int ql, int qr){
    
    
	if(ql <= left && qr >= right) return tree[node];
	string *res = &init;
	int mid = (left + right) >> 1;
	if(ql <= mid) res = str_max(res, query(node << 1, left, mid, ql, qr));
	if(mid < qr) res = str_max(res, query(node << 1 | 1, mid + 1, right, ql, qr));
	return res;
}

int main(){
    
    
	
	scanf("%d", &N);
	char buf[20];
	for(int i = 1; i <= N; i++){
    
    
		scanf("%s", buf);
		words[i] = string(buf);
		//cin >> words[i];
	}
	build(1, 1, N);
	scanf("%d", &M);
	int l, r;
	for(int i = 1; i <= M; i++){
    
    
		scanf("%d%d", &l, &r);
		for(auto &ch : *query(1, 1, N, l, r)) putchar(ch);
		putchar('\n');
		//printf("%s\n", query(1, 1, N, l, r).c_str());
		//cout << query(1, 1, N, l, r) << "\n";
	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/m0_46161993/article/details/108198678