uva11235: frequency values (st table)

Give an array of integers in non descending order, a1,a2 Your task is to answer a series of questions (i,j), ai,ai + 1 , the number of times the most frequent value appears in aj.

Input format: multiple groups of data, input n and q in the first row of each group of data, (1 < = n, q < = 100000). The second line contains n integers a1,a2 ,an (-100000 <= ai <= 100000). Each of the following q lines includes two integers i and J (1 < = I < = J < = n), and the input end standard is n = 0.

Practice analysis: note that the given sequence is non descending, which means that the same elements in the middle will be arranged together. If it is not non descending, it is really not easy to do. Since it is a group together, a group of data can be shrunk together, represented by a binary (a,b), indicating that the element with a value appears B times.

For each pair of I and j, the clique of the i-th element and the clique of the j-th element are incomplete, and all the cliques in the middle are complete. First, the size of two incomplete cliques on both sides is obtained: ans = max(R[i] - i + 1,j - L[j] +1). RMQ can be used to query the complete group in the middle. Note that I and j are in one regiment and there are only two regiments in total.

Here you can use subscript mapping or value mapping, because I've written the subscript mapping and changed it to value mapping.

#include<bits/stdc++.h> 
using namespace std;
#define pii pair<int,int>
const int maxn = 1e5 + 10;
const int mx = 18;
int n,q;
int val[maxn];
int lef[maxn * 3],rig[maxn * 3],mp[3 * maxn];
int st[maxn - 1][mx - 1];
vector<pii> g;
int Hash(int x) {
	return x + 100000;	
}
void init() {
	memset(lef,-1,sizeof(lef));
	memset(rig,-1,sizeof(rig));
	memset(val,-1,sizeof(val));
	memset(mp,-1,sizeof(mp));
	memset(st,0,sizeof(st));	
	g.clear();
}
int main() {
	while(scanf("%d",&n) && n) {
		scanf("%d",&q);
		init();
		int last = 0x3f3f3f3f;
		for(int i = 1; i <= n; i++) {
			scanf("%d",&val[i]);
			if(val[i] == last)
				rig[Hash(val[i])] = i;
			else {
				if(i != 1) {
					g.push_back(pii(val[i - 1],rig[Hash(val[i - 1])] - lef[Hash(val[i - 1])] + 1));
					mp[Hash(val[i - 1])] = g.size() - 1;
				}
				last = val[i];
				lef[Hash(val[i])] = i;
				rig[Hash(val[i])] = i;
			}
		}
		
		rig[Hash(val[n])] = n; 
		g.push_back(pii(val[n],rig[Hash(val[n])] - lef[Hash(val[n])] + 1));
		mp[Hash(val[n])] = g.size() - 1;
		
		int len = g.size() - 1;
		for(int i = 0; i <= len; i++) 
			st[i][0] = g[i].second;
		for(int j = 1; (1 << j) <= len; j++)
			for(int i = 0; i + (1 << j) - 1 <= len; i++)
				st[i][j] = max(st[i][j - 1],st[i + (1 << (j - 1))][j - 1]);
				
		for(int i = 1; i <= q; i++) {
			int l,r;
			int ans = 0;
			scanf("%d%d",&l,&r);
			if(val[l] == val[r])
				ans = r - l + 1;
			else {
				int vl = Hash(val[l]),vr = Hash(val[r]); 
				ans = max(rig[vl] - l + 1,r - lef[vr] + 1);
				int sta = mp[vl] + 1, en = mp[vr] - 1;
				if(sta <= en) {
					int li = en - sta + 1;
					int k = (int) (log((double)li) / log(2.0));
					ans = max(ans,max(st[sta][k],st[en - (1 << k) + 1][k]));
				}
			}
			printf("%d\n",ans);
		}
	}
	return 0;
}	

Posted by sys4dm1n on Mon, 18 Nov 2019 09:58:14 -0800