• AtCoder Regular Contest 069 E


    E - Frequency
    Time limit : 2sec / Memory limit : 256MB

    Score : 700 points

    Problem Statement
    Snuke loves constructing integer sequences.

    There are N piles of stones, numbered 1 through N. The pile numbered i consists of ai stones.

    Snuke will construct an integer sequence s of length Σai, as follows:

    Among the piles with the largest number of stones remaining, let x be the index of the pile with the smallest index. Append x to the end of s.
    Select a pile with one or more stones remaining, and remove a stone from that pile.
    If there is a pile with one or more stones remaining, go back to step 1. Otherwise, terminate the process.
    We are interested in the lexicographically smallest sequence that can be constructed. For each of the integers 1,2,3,…,N, how many times does it occur in the lexicographically smallest sequence?

    Constraints
    1≤N≤105
    1≤ai≤109
    Input
    The input is given from Standard Input in the following format:

    N
    a1 a2 … aN
    Output
    Print N lines. The i-th line should contain the number of the occurrences of the integer i in the lexicographically smallest sequence that can be constructed.

    Sample Input 1
    Copy
    2
    1 2
    Sample Output 1
    Copy
    2
    1
    The lexicographically smallest sequence is constructed as follows:

    Since the pile with the largest number of stones remaining is pile 2, append 2 to the end of s. Then, remove a stone from pile 2.
    Since the piles with the largest number of stones remaining are pile 1 and 2, append 1 to the end of s (we take the smallest index). Then, remove a stone from pile 2.
    Since the pile with the largest number of stones remaining is pile 1, append 1 to the end of s. Then, remove a stone from pile 1.
    The resulting sequence is (2,1,1). In this sequence, 1 occurs twice, and 2 occurs once.

    Sample Input 2
    10
    1 2 1 3 2 4 2 5 8 1
    Sample Output 2
    10
    7
    0
    4
    0
    3
    0
    2
    3
    0

    题意:有N堆石头,每堆石头有Ai个石头,每次可从任意一堆石头中取出一个石头,然后取所有堆中石头个数最大的值,放到序列S中,现在要将所有石头拿完,以构造一个序列S,并使得这个序列S的是字典序最小的,问,这个字典序最小的序列,每个数字1~N各出现了多少次。

    对于多个最大堆的情况,肯定一直选位序最小的作为序列S中填入的数值。然后在保持这个最大堆的基础上,将该序号之前大于等于最大堆的石头都拿到和次大堆都一样的数量,当然最后拿的是之前一直塞到S序列中标号的那一堆。然后对于次大堆同样削去和次次大堆一样的层数。这个多出来的总和即次大堆最小标号出现的次数

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    #define LL long long
    using namespace std;
    const int maxn=1e5+10;
    struct node
    {
        LL pos,val;
    } a[maxn];
    bool cmp(node a,node b)
    {
        if(a.val==b.val)return a.pos<b.pos;
        return a.val>b.val;
    }
    int n;
    LL ans[maxn];
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            memset(ans,0,sizeof ans);
            for(int i=1; i<=n; i++)
            {
                scanf("%lld",&a[i].val);
                a[i].pos=i;
            }
            sort(a+1,a+n+1,cmp);
            a[n+1].val=0;
            LL tmp=1;
            int num=a[1].pos;
            for(int i=2; i<=n+1; i++)
            {
                if(a[i].val==a[i-1].val) tmp++;
                else ans[num]+=(a[i-1].val-a[i].val)*tmp,tmp++;
                if(a[i].pos<num) num=a[i].pos;
            }
            for(int i=1;i<=n;i++)printf("%lld
    ",ans[i]);
        }
    }
    /*
    6
    1 3 2 3 3 3
    */
    
  • 相关阅读:
    编译原理:算符优先分析
    编译原理:自下而上语法分析
    编译原理:实验二 递归下降语法分析
    编译原理:LL(1)文法的判断,递归下降分析程序
    作业9 DFA最小化
    作业8 非确定的自动机NFA确定化为DFA
    作业7 正规式到正规文法与自动机
    作业6 正规文法与正规式
    作业5 词法分析程序的设计与实现
    作业4 文法和语言总结与梳理
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11135753.html
Copyright © 2020-2023  润新知