• Feel Good(POJ 2796)树状数组+单调栈


    题意:

    一排数,找到一个区间,使得该区间内 所有数之和乘以该区间内的最小数 最大,输出该最大值和区间左右端点。

    Sample Input

    6
    3 1 6 4 5 2
    

    Sample Output

    60
    3 5

    冉了我好久的一道单调栈的题,毕竟我也是刚入门。

    注意的一点:ans初值要赋为-1,如果默认赋为0,当我们的数据最大值为0时就无法操作

     

    代码如下:

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int MX=1e5+100;
    int n;
    long long a[MX],bit[MX],L[MX],R[MX],stk[MX],top;
    
    int lowbit(int x){
        return x&-x;
    }
    
    void update(int x,int add)
    {
        for(;x<=n;x+=lowbit(x))
            bit[x]+=add;
    }
    
    long long sum(int x)
    {
        long long tot=0;
        for(;x;x-=lowbit(x))
            tot+=bit[x];
        return tot;    
    }
    
    void sol()
    {
        while(top>0) top--;
        for(int i=1;i<=n;++i)
        {
            while(top>0 && a[i]<=a[stk[top]]) top--;
            if(top==0)  L[i]=0;
            else        L[i]=stk[top];
            stk[++top]=i;                 
        }
        
        while(top>0) top--;
        for(int i=n;i>=1;--i)
        {
            while(top>0 && a[i]<=a[stk[top]]) top--; 
            if(top==0)  R[i]=n+1;
            else        R[i]=stk[top];
            stk[++top]=i;
        }
    }
    
    long long bin(int l,int r)
    {
        return sum(r)-sum(l-1);
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            memset(bit,0,sizeof(bit));
            for(int i=1;i<=n;++i)
            {
                scanf("%d",&a[i]);
                update(i,a[i]);
            }
        
            sol();
            long long ans=-1;
            int l,r;
            for(int i=1;i<=n;++i)
            {
                long long t=bin(L[i]+1,R[i]-1)*a[i];
                if(t>ans)
                {
                    ans=t;
                    l=L[i]+1;
                    r=R[i]-1;
                }
            }
            printf("%lld
    %d %d
    ",ans,l,r);
        }
        return 0;
    }
    /*
    6
    3 1 6 4 5 2
    */
    从0到1很难,但从1到100很容易
  • 相关阅读:
    USACO2.2 Preface Numbering【思维+打表】
    USACO2.1 Hamming Codes【枚举+二进制处理+输出格式+题意理解】
    USACO1.6 Healthy Holsteins【dfs/bfs 爆搜】
    USACO1.5 Mother's Milk【搜索】
    USACO1.6 Number Triangles [dp-简单dp]
    USACO1.6 回文质数 Prime Palindromes
    泛型简介
    涉及 C#的 foreach问题
    c#委托事件及其讲解
    WPF 打印 包括设置,打印预览,打印等等
  • 原文地址:https://www.cnblogs.com/qseer/p/9398108.html
Copyright © 2020-2023  润新知