poj2352_II和III
这个题的第二个版本:
同2299_II,也是压缩到1--n范围内,找出已知序列的相对顺序,然后构建树状数组。这里也需要一个辅助的数组。
代码:
View Code
1 #include <iostream> 2 #include <stdio.h> 3 #include <memory.h> 4 #include <algorithm> 5 using namespace std; 6 //516k 188ms 7 const int maxnum=15001; 8 struct node 9 { 10 int digit; 11 int number; 12 }array[maxnum],t[maxnum]; //t辅助数组 13 int tree[maxnum]; 14 int res[maxnum]; 15 int n; 16 17 void update(int index,int add) 18 { 19 while(index<=n) 20 { 21 tree[index]+=add; 22 index+=(-index)&index; 23 } 24 } 25 26 int getsum(int index) //原序列中index位置之前小于等于array[index]的个数 27 { 28 int sum=0; 29 while(index>0) 30 { 31 sum+=tree[index]; 32 index-=(-index)&index; 33 } 34 return sum; 35 } 36 37 bool cmp(struct node a,struct node b) 38 { 39 if(a.digit==b.digit) //因为我离散化了,然后坐标里有重复的数字,因此需要在这里保存稳定性 40 return a.number<b.number; 41 return a.digit<b.digit; 42 } 43 44 45 int main() 46 { 47 scanf("%d",&n); 48 int i,temp; 49 for(i=1;i<=n;i++) 50 { 51 scanf("%d%d",&array[i].digit,&temp); 52 t[i].digit=array[i].digit; 53 t[i].number=i; 54 } 55 sort(t+1,t+1+n,cmp); 56 57 for(i=1;i<=n;i++) 58 array[t[i].number].number=i; //得到相对位置 59 memset(tree,0,sizeof(tree)); 60 memset(res,0,sizeof(res)); 61 for(i=1;i<=n;i++) 62 { 63 update(array[i].number,1); 64 res[getsum(array[i].number)-1]++; //这里要减一,不包括它本身 65 } 66 for(i=0;i<n;i++) 67 printf("%d\n",res[i]); 68 return 0; 69 } 70 71 /* 72 5 73 1 1 74 5 1 75 7 1 76 3 3 77 5 5 78 */
第三个版本不需要压缩,直接离散到大于等于1的范围内即可
View Code
1 #include <iostream> 2 #include <stdio.h> 3 #include <memory.h> 4 #include <algorithm> 5 using namespace std; 6 //408k 125ms 7 const int maxnum=15001; 8 const int maxdigit=32005; 9 int array[maxnum]; //t辅助数组 10 int tree[maxdigit]; 11 int res[maxnum]; 12 int n; 13 14 void update(int index,int add) 15 { 16 while(index<maxdigit) 17 { 18 tree[index]+=add; 19 index+=(-index)&index; 20 } 21 } 22 23 int getsum(int index) //原序列中index位置之前小于等于array[index]的个数 24 { 25 int sum=0; 26 while(index>0) 27 { 28 sum+=tree[index]; 29 index-=(-index)&index; 30 } 31 return sum; 32 } 33 34 int main() 35 { 36 scanf("%d",&n); 37 int i,temp; 38 for(i=1;i<=n;i++) 39 scanf("%d%d",&array[i],&temp); 40 41 memset(tree,0,sizeof(tree)); 42 memset(res,0,sizeof(res)); 43 for(i=1;i<=n;i++) 44 { 45 update(array[i]+1,1); 46 res[getsum(array[i]+1)-1]++; //这里要减一,不包括它本身 47 } 48 for(i=0;i<n;i++) 49 printf("%d\n",res[i]); 50 return 0; 51 } 52 53 /* 54 5 55 1 1 56 5 1 57 7 1 58 3 3 59 5 5 60 */