1636: Pascal山脉
提交: 51 解决: 15
[提交][状态][讨论版]
题目描述
输入
输出
样例输入
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 }