• [POJ3368][UVA11235] Frequent values[ST表]


    题意:给出一个不降序列,有多个询问,询问[l,r]中出现次数最多的数的出现次数

    多组数据

    对于序列-1 -1 1 1 1 1 3 10 10 10

    可以这么理解<-1,2>, <1, 4>, ❤️,1>, <10,3>

    cnt[i]记录这个数字的出现次数,lef[i]记录左端点,righ[i]记录右端点,belong[i]代表第i个数字属于哪一块

    把块和数量丢进st表
    然后对于区间[l,r],答案就是 (min(r, righ[l])-l+1)(r-max(l, lef[r])+1)(RMQ(belong[l]+1,belong[r]-1))中最大的一个
    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    
    const int inf = 0x3f3f3f3f;
    inline void chmax(int &x, int y) {if (x < y) x = y;}
    inline void chmin(int &x, int y) {if (x > y) x = y;}
    const int MAXN = 1e5+7;
    int n, m, st[21][MAXN], a[MAXN], len[MAXN], belong[MAXN], lef[MAXN], righ[MAXN], tot, cnt[MAXN], Pow[21], logg[MAXN];
    inline int read() {
    	int c = getchar(), f = 1, x = 0;
    	while(!isdigit(c)) (c=='-')&&(f=-f), c = getchar();
    	while(isdigit(c)) x = x * 10 + c - '0', c = getchar();
    	return x * f;
    }
    inline int RMQ(int l, int r) {
    	int k = logg[r-l+1];
    	return max(st[k][l], st[k][r-Pow[k]+1]);
    }
    int main(void) {
    	for(int i = 2; i <= 100000; ++i) logg[i] = logg[i>>1] + 1;
    	for(int i = 0; i <= 20; ++i) Pow[i] = (1<<i);
    	while((n = read())) {
    		tot = 0; memset(cnt, 0, n*4);
    		m = read();
    		for(int i = 1; i <= n; ++i) a[i] = read();	
    		for(int i = 1; i <= n; ++i) {
    			if (a[i] != a[i-1]) lef[i] = i, belong[i] = ++tot;
    			else lef[i] = lef[i-1], belong[i] = tot;
    			++cnt[tot];
    		}
    		for(int i = n; i >= 1; --i) {
    			if (a[i] != a[i+1]) righ[i] = i;
    			else righ[i] = righ[i+1];
    		}
    		for(int i = 1; i <= tot; ++i) st[0][i] = cnt[i];
    //		for(int i = 1; i <= n; ++i) cout << lef[i] << " 
    "[i==n];
    //		for(int i = 1; i <= n; ++i) cout << righ[i]<< " 
    "[i==n];
    //		for(int i = 1; i <= n; ++i) cout << belong[i]<<" 
    "[i==n];
    //		for(int i = 1; i <= tot; ++i) cout << cnt[i] << " 
    "[i==n];
    		int mm = logg[n];
    		for(int i = 1; i <= mm; ++i)
    			for(int j = 1; j <= tot; ++j)
    				st[i][j] = max(st[i-1][j], st[i-1][j+Pow[i-1]]);
    		while(m--) {
    			int l = read(), r = read();
    			if (belong[l] == belong[r]) printf("%d
    ", r-l+1);
    			else {
    				int ans = min(r, righ[l]) - l + 1;
    				chmax(ans, r - max(l, lef[r]) + 1);
    				if (belong[l] + 1 <= belong[r] - 1) chmax(ans, RMQ(belong[l]+1, belong[r] - 1));
    				printf("%d
    ", ans);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    精品绿色便携软件下载站
    DIV + CSS
    CSS基础
    尘封往事
    最近ゲームにはまってる。
    比水更浓的水
    有些事我得记下来
    一年前的今晚,注定是个岔路口.
    放下全世界
    超级保镖:国外精品个人防火墙亲密接触(2) java程序员
  • 原文地址:https://www.cnblogs.com/storz/p/10191551.html
Copyright © 2020-2023  润新知