微信扫一扫打赏支持

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\n",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\n",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 }

 

posted @ 2017-11-03 00:15  范仁义  阅读(744)  评论(0编辑  收藏  举报