51nod 1280 prefix suffix set

Topic source: Codility
Baseline Time Limit: 1 second Space Limit: 131072 KB Score: 40 Difficulty: Level 4 Algorithm Questions
collect
focus on
An array contains N positive integers, some of which are repeated. A prefix-suffix set is a subscript pair (P,S) that satisfies the condition that 0<= P,S < N satisfies the value of the array element A[0..P] is also in A[S..N - 1] value appears, and the value in A[S..N - 1] also appears in A[0..P]. In other words the set of prefixes A[0..P] contains exactly the same values ​​as the set of suffixes A[S..N - 1]. Find the number of such prefix-suffix sets.

For example: 3 5 7 3 3 5, a total of 14 sets meet the conditions: (1, 4), (1, 3), (2, 2), (2, 1), (2, 0), (3, 2 ), (3, 1), (3, 0), (4, 2), (4, 1), (4, 0), (5, 2), (5, 1), (5, 0)
This question was translated by @javaman  .  



Input


Line 1: A number N, representing the length of the array (1 <= N <= 50000). Lines 2 - N + 1: 1 number per line, corresponding to element Ai in the array. (1 <= Ai <= 10^9)


Output


Output the number of sets that meet the condition.


Input example


6357335


Output example


14


Idea: Record the number of types of numbers that appear in each position in positive order, and also record the number of types of each position in reverse order, enumerate the number of types from large to small, if the number of types is reduced by one, then judge whether the subtracted numbers are the same or not. just jump out. Special sentence 1 and all kinds of numbers.
PS: The data is too weak, not sure if it is a positive solution (in the beginning, the subscript of the binary search was increased by 1, and there was only one set of data!!!!)

Code:
#include <bits/stdc++.h>
#define INF 1e9
using namespace std;
const int AX = 5e4+66;
int a[AX];
int pre[AX];
int rear[AX];
map<int,int>mp;
int main(){
	int n ;
	scanf("%d",&n);
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&a[i]);
	}
	memset( pre , 0 ,sizeof(pre) );
	memset( rear , 0 ,sizeof(rear) );
	mp [a [0]] = 1;
	pre[0] = 1;
	for( int i = 1 ; i < n ; i ++ ){
		if( !mp[a[i]] ){
			mp [a [i]] = 1;
			pre[i] = pre[i-1] + 1;
		}else{
			pre[i] = pre[i-1];
		}
	}
	mp.clear();
	mp [a [n-1]] = 1;
	rear[0] = 1;
	for( int i = n - 2 ; i >= 0 ; i -- ){
		if( !mp[a[i]] ){
			mp [a [i]] = 1;
			rear[n-1-i] = rear[n-i-2] + 1 ;
		}else{
			rear[n-1-i] = rear[n-i-2];
		}
	}
	int num = pre[n-1];
	int res = 0;
	int pos1 = lower_bound (pre, pre + n, num) -pre;
	int pos2 = lower_bound( rear , rear + n , num )-rear;
	int id1 = pos1;
	int id2 = pos2;
	int x1 = n - pos1;
	int x2 = n - pos2;
	res += x1 * x2;
	for( int i = num - 1 ; i >= 2 ; i -- ){
		if( a[pos1] == a[n-1-pos2] ){
			pos1 = lower_bound( pre , pre + n , i ) - pre;
			pos2 = lower_bound( rear , rear + n , i ) - rear;
			res += ( pos1 - id1 ) * ( pos2 - id2 );
			id1 = pos1;
			id2 = pos2;	
		}else break;
	}
	pos1 = upper_bound( pre , pre + n , 1 ) - pre;
	pos2 = upper_bound( rear , rear + n , 1 ) - rear;
	if( a[0] == a[n-1] ){
		res += ( pos1 ) * ( pos2 );
	}
	cout << res << endl;
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325730730&siteId=291194637