zoukankan      html  css  js  c++  java
  • P2866 [USACO06NOV]糟糕的一天Bad Hair Day

    题意:给你一个序列,问将序列倒过来后,对于每个点,在再碰到第一个比它大的点之前,有多少比它小的?  

       求出比它小的个数的和

    样例:

    6
    10
    3
    7
    4
    12
    2

    output: 5

    倒序后:2    12    4    7    3   10   6

    答案:   0     1     0     1    0     3    0

    因此最终输出1+1+3=5

    虽然是单调栈裸题(打完暴力才刚看出来

    不过我还是坚持写了暴力(明明是刚开始没思路

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define int long long
    #define olinr return
    #define _ 0
    #define love_nmr 0
    #define DB double
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    int n;
    int a[80505];
    int tot;
    int ans;
    signed main()
    {
        n=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        for(int i=1;i<=n;i++)
        {
            tot=0;
            int now=i+1;
            while(now<=n&&a[now]<a[i])
            {
                tot++;
                now++;
            }
            ans+=tot;
        }
        put(ans);
        olinr ~~(0^_^0)+love_nmr;
    }
    $O(n^2)$暴力

    正解:单调栈

    考虑维护一个从下到上递减的栈

    来一个数1、比栈顶大---》一直弹并统计答案,最后入栈

    否则直接入栈

    然而。。。。WA

    比如12    4   7   3    10

    7来的时候,我们把4 弹了出去

    但是等10来的时候,4可是要统计进答案的啊

    而我们已经把它弹出去了!

    怎么办呢?

    请教大佬之后发现)很简单

    栈中不再维护元素值,维护元素下标!

    入栈入的是下标

    这样在弹栈的时候直接让下标作差就可以求出直接有多少数

    避免了答案的漏洞

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define int long long
    #define olinr return
    #define _ 0
    #define love_nmr 0
    #define DB double
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    int n;
    int a[80505];
    int ans;
    struct node
    {
        int tp;
        int s[80505];
        void pop()
        {
            tp--;
        }
        int top()
        {
            return s[tp];
        }
        bool empty()
        {
            return tp==0;
        }
        void push(int x)
        {
            tp++;
            s[tp]=x;
        }
        int size()
        {
            return tp;
        }   
    }s;   //手写栈就是快@!
    int tot;
    signed main()
    {
        n=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        s.push(n+1);
        a[n+1]=0x7fffffff;   //便于求tot
        for(int i=n;i>=1;i--)
        {
            if(s.empty())
            {
                s.push(i);   //推下标
                continue;
            } 
            if(a[i]<a[s.top()])   //比的时候注意存的是下标
            {
                s.push(i);   //推下标
                continue;
            }
            while(!s.empty()&&a[s.top()]<a[i])
                s.pop();
            ans+=s.top()-i-1;   //统计
            s.push(i);
            // ans+=tot;
        }
        put(ans);
        olinr ~~(0^_^0)+love_nmr;
    }
  • 相关阅读:
    软件工程-个人最终总结
    结对编程—电梯调度
    第三周(第三作业)感想
    周三第二个作业
    VS2013安装和单元测试
    对京东的评价
    简单的四则运算
    迷茫的软件工程
    vlan 和 子网
    ECLIPSE的jar包和文件的导入导出
  • 原文地址:https://www.cnblogs.com/olinr/p/9599567.html
Copyright © 2011-2022 走看看