zoukankan      html  css  js  c++  java
  • 【51nod】1564 区间的价值

    题解

    这个要注意到一个长度大的区间的最大价值一定比长度小的区间的价值要大
    然后我们以每个点为最小值,显然区间越长最大值越大,然后我们更新最大区间长度的取值,这个可以用单调栈求这个最小值能更新到的左右端点
    最后处理成后缀最大值

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <ctime>
    #include <vector>
    #include <set>
    //#define ivorysi
    #define eps 1e-8
    #define mo 974711
    #define pb push_back
    #define mp make_pair
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define MAXN 100005
    #define space putchar(' ')
    #define enter putchar('
    ')
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    int N,le[MAXN],ri[MAXN],sta[MAXN],top,st[MAXN][20],len[MAXN];
    int64 a[MAXN],suf[MAXN];
    
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
    }
    template<class T>
    void out(T x) {
        if(x < 0) {putchar('-');x = -x;}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    void Init() {
        read(N);
        for(int i = 1 ; i <= N ; ++i) read(a[i]);
        for(int i = 2 ; i <= N ; ++i) len[i] = len[i / 2] + 1;
        for(int i = 1 ; i <= N ; ++i) {
    	st[i][0] = a[i];
        }
        for(int j = 1 ; j <= 19 ; ++j) {
    	for(int i = 1 ; i <= N ; ++i) {
    	    if(i + (1 << j) - 1 > N) break;
    	    st[i][j] = max(st[i][j - 1],st[i + (1 << j - 1)][j - 1]);
    	}
        }
        top = 0;
        for(int i = 1 ; i <= N ; ++i) {
    	while(top > 0 && a[i] < a[sta[top]]) {
    	    ri[sta[top]] = i - 1;
    	    --top;
    	}
    	if(!top) le[i] = 1;
    	else le[i] = sta[top] + 1;
    	sta[++top] = i;
        }
        for(int i = 1 ; i <= top ; ++i) ri[sta[i]] = N;
    }
    void Solve() {
        for(int i = 1 ; i <= N ; ++i) {
    	int k = ri[i] - le[i] + 1;
    	int64 x = max(st[le[i]][len[k]],st[ri[i] - (1 << len[k]) + 1][len[k]]);
    	suf[k] = max(suf[k],x * a[i]);
        }
        for(int i = N ; i >= 1 ; --i) suf[i] = max(suf[i],suf[i + 1]);
        for(int i = 1 ; i <= N ; ++i) {
    	out(suf[i]);enter;
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Init();
        Solve();
        return 0;
    }
    
    
  • 相关阅读:
    uniapp 常用的基础知识
    uniapp接口请求(第一种)
    系统对象的使用——Cookie,ViewState,Session,Application
    网页跳转
    存储过程的使用——游标
    存储过程的使用——循环,条件语句
    存储过程的使用——定义变量
    页面读取英语单词
    加密
    XMind: ZEN 快捷键
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9070240.html
Copyright © 2011-2022 走看看