• 1636: Pascal山脉


    1636: Pascal山脉

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 51  解决: 15
    [提交][状态][讨论版]

    题目描述

    小卡卡顺着老者所指的方向,来到了Pascal神峰的顶峰。老者告诉小卡卡,Pascal山脉有很多座山, 都排在一条直线上,每座山都有不同的高度。Pascal山的山顶有一个神奇的洞穴,进入这个洞穴后,你将会到达这座山前方的另一座山,更加神奇的是,你到达的山一定比他所在的山高度要小。而Pascal圣地最大的宝藏就藏在某一座Pascal山上的洞穴中,这个洞穴的特点是它有一道石门封闭着。小卡卡很想知道进入每座山的洞穴后,他所到达的不同的山会有多少种可能。

    输入

    第一行一个整数n,表示山的个数.(1<=n<=20000) 第二行有n个整数,从前到后给出每座山的高度。另外两座山可以有相同的高度. (1<=每座山的高度<=maxlongint)

    输出

    共一行n个整数,互相以一个空格分隔。.第i个整数表示他进入第i号山的洞穴后能够到达的不同的山的个数.

    样例输入

    5		     
    1 2 3 4 5

    样例输出

    0 1 2 3 4

    提示

    前10点n<=20000;

    第11点n=35000;

    第12点n=50000;

    第13点n=100000;



    考试时,建议:

    if n<=13000 then begin

    算法1:O(n方)的模拟算法,n方/2次运算量。

    else begin

    算法2或算法3

    end;

    来源

    分析:

    数状数组

    分析:离散化+树状数组

    【参考程序】:

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    struct node
    {
        
    int x,y;
    } a[200001];
    int b[200001],c[200001];
    int n,len;
    int cmp(const void *s,const void *t)
    {
        node i=*(node *)s,j=*(node *)t;
        
    return i.x-j.x;
    }
    int lowbit(int x)
    {
        
    return x^(x&(x-1));//x&(-x)
    }
    void modify(int x)
    {
        
    while (x<=len)
        {
            c[x]++;
            x+=lowbit(x);
        }
    }
    int getsum(int x)
    {
        
    int s=0;
        
    while (x)
        {
            s+=c[x];
            x-=lowbit(x);
        }
        
    return s;
    }
    int main()
    {
        
    //freopen("a1.in","r",stdin);
        //freopen("a1.out","w",stdout);

        while (scanf("%d",&n)!=EOF)
        {
            
    for (int i=1;i<=n;i++)
            {
                scanf("%d",&a[i].x);
                a[i].y=i;
            }
            qsort(a+1,n,
    sizeof(node),cmp);
            a[0].x=-1;
            len=0;
            
    for (int i=1;i<=n;i++)
            {
                
    if (a[i].x!=a[i-1].x) len++;
                b[a[i].y]=len;
            }
            memset(c,0,
    sizeof(c));
            
    for (int i=1;i<=n;i++)
            {
                
    int sum=getsum(b[i]-1);
                printf("%d ",sum);
                modify(b[i]);
            }
        }
        
    return 0;
    }

    5

    7 3 6 4 2

    1 2 3 4 5

    0 0 1 1 0

    找比它小个数

    排序后

    x:7 6 4 3 2

    y:1 3 4 2 5

    7 3 6 4 2

    b[i] 5 2 4 3 1

    0 0 1 1 0

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include <bits/stdc++.h>
     5 using namespace std;
     6 struct node
     7 {
     8     int x,y;
     9 } a[200001];
    10 int b[200001],c[200001];
    11 int n,len;
    12 //比较规则,按x从大到小排序 
    13 int cmp(const void *s,const void *t)
    14 {
    15     node i=*(node *)s,j=*(node *)t;
    16     return i.x-j.x;
    17 }
    18 //lowbit操作 
    19 int lowbit(int x)
    20 {
    21     return x^(x&(x-1));
    22 }
    23 //修改操作 
    24 void modify(int x)
    25 {
    26     while (x<=len)
    27     {
    28         c[x]++;
    29         x+=lowbit(x);
    30     }
    31 }
    32 //取前缀和 
    33 int getsum(int x)
    34 {
    35     int s=0;
    36     while (x)
    37     {
    38         s+=c[x];
    39         x-=lowbit(x);
    40     }
    41     return s;
    42 }
    43 int main()
    44 {
    45     freopen("in.txt","r",stdin);
    46     //freopen("a1.out","w",stdout);
    47     while (scanf("%d",&n)!=EOF)
    48     {
    49         for (int i=1;i<=n;i++)
    50         {
    51             scanf("%d",&a[i].x);
    52             a[i].y=i;
    53         }
    54         qsort(a+1,n,sizeof(node),cmp);
    55         a[0].x=-1;
    56         len=0;
    57         //离散化 
    58         for (int i=1;i<=n;i++)
    59         {
    60             if (a[i].x!=a[i-1].x) len++;
    61             //这里y等于i 
    62             b[a[i].y]=len;
    63         }
    64         for (int i=1;i<=n;i++){
    65             cout<<b[i]<<" "; 
    66         } 
    67         cout<<endl;
    68         memset(c,0,sizeof(c));
    69         for (int i=1;i<=n;i++)
    70         {
    71             //从大到小排序,找比它小的 
    72             int sum=getsum(b[i]-1);
    73             printf("%d
    ",sum);
    74             modify(b[i]);
    75             for (int i=1;i<=n;i++){
    76                 cout<<c[i]<<" ";
    77             }
    78             cout<<endl;
    79         }
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    2016.07.24
    这个月
    PL/SQL: numeric or value error: character to number conversion error
    java下double相乘精度丢失问题
    Oracle中实现find_in_set
    oracle中,改变表名和字段名的大小写
    Unknown entity XXX
    Incorrect column count: expected 1, actual 5
    负数的二进制表示
    【Android】Android单例模式及使用单例模式实现自己的HttpClient工具类
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7775333.html
Copyright © 2020-2023  润新知