• [JOISC2014]歴史の研究/[BZOJ4241]历史研究


    [JOISC2014]歴史の研究/[BZOJ4241]历史研究

    题目大意:

    一个长度为(n(nle10^5))的数列(A(A_ile10^9)),定义一个元素对一个区间([l,r])的贡献为(A_i imes cnt(A_i)),其中(cnt(A_i))表示(A_i)在区间内的出现次数。(q(qle10^5))次询问,每次询问一个区间内贡献最大的元素的贡献。

    思路:

    分块。

    (cnt[i][j])表示前(i)块内(j)的出现次数,(sum[i][j])表示([begin(i),end(j)])的答案。

    (A)离散化后预处理(cnt)(sum),询问时如果(l,r)在同一块直接暴力。如果不在同一块,则答案要么是(sum[bel(l)+1,bel(r)-1]),要么是(l,r)所在块中出现过的元素的贡献。

    时间复杂度(mathcal O(n^{frac32}))

    源代码:

    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    typedef long long int64;
    const int N=1e5,M=317;
    int n,m,q,block,a[N],b[N],bel[N],begin[M],end[M],tmp[N],cnt[M][N];
    int64 sum[M][M];
    inline int64 query(const int &l,const int &r) {
    	int64 ret=0;
    	if(bel[l]==bel[r]) {
    		for(register int i=l;i<=r;i++) {
    			tmp[a[i]]++;
    			ret=std::max(ret,(int64)b[a[i]]*tmp[a[i]]);
    		}
    		for(register int i=l;i<=r;i++) tmp[a[i]]--;
    		return ret;
    	}
    	ret=sum[bel[l]+1][bel[r]-1];
    	for(register int i=l;i<=end[bel[l]];i++) {
    		tmp[a[i]]++;
    		ret=std::max(ret,(int64)b[a[i]]*(tmp[a[i]]+cnt[bel[r]-1][a[i]]-cnt[bel[l]][a[i]]));
    	}
    	for(register int i=begin[bel[r]];i<=r;i++) {
    		tmp[a[i]]++;
    		ret=std::max(ret,(int64)b[a[i]]*(tmp[a[i]]+cnt[bel[r]-1][a[i]]-cnt[bel[l]][a[i]]));
    	}
    	for(register int i=l;i<=end[bel[l]];i++) tmp[a[i]]--;
    	for(register int i=begin[bel[r]];i<=r;i++) tmp[a[i]]--;
    	return ret;
    }
    int main() {
    	n=getint(),q=getint(),block=sqrt(n);
    	for(register int i=0;i<n;i++) {
    		a[i]=b[i]=getint();
    		bel[i]=i/block;
    		end[bel[i]]=i;
    	}
    	for(register int i=n-1;i>=0;i--) {
    		begin[bel[i]]=i;
    	}
    	std::sort(&b[0],&b[n]);
    	m=std::unique(&b[0],&b[n])-b;
    	for(register int i=0;i<n;i++) {
    		a[i]=std::lower_bound(&b[0],&b[m],a[i])-b;
    		cnt[bel[i]][a[i]]++;
    	}
    	for(register int i=1;i<=bel[n-1];i++) {
    		for(register int j=0;j<m;j++) {
    			cnt[i][j]+=cnt[i-1][j];
    		}
    	}
    	for(register int i=0;i<=bel[n-1];i++) {
    		for(register int j=begin[i];j<=end[i];j++) {
    			tmp[a[j]]++;
    			sum[i][i]=std::max(sum[i][i],(int64)b[a[j]]*tmp[a[j]]);
    		}
    		for(register int j=begin[i];j<=end[i];j++) tmp[a[j]]--;
    		for(register int j=i+1;j<=bel[n-1];j++) {
    			sum[i][j]=sum[i][j-1];
    			for(register int k=begin[j];k<=end[j];k++) {
    				tmp[a[k]]++;
    				sum[i][j]=std::max(sum[i][j],(int64)b[a[k]]*(tmp[a[k]]+cnt[j-1][a[k]]-(i!=0?cnt[i-1][a[k]]:0)));
    			}
    			for(register int k=begin[j];k<=end[j];k++) tmp[a[k]]--;
    		}
    	}
    	for(register int i=0;i<q;i++) {
    		const int l=getint()-1,r=getint()-1;
    		printf("%lld
    ",query(l,r));
    	}
    	return 0;
    }
    
  • 相关阅读:
    js-link下载文件
    sql-优化建议
    Studio-环境变量设置
    Studio
    Docker下安装ElasticSearch和Kibana
    sklearn 中的 r2_score
    R语言将所有列数据正交化/缩放
    R语言 random forests out-of-bag prediction
    R语言 coalesce 函数
    R语言 case_when 函数
  • 原文地址:https://www.cnblogs.com/skylee03/p/9502301.html
Copyright © 2020-2023  润新知