这里介绍另外一种解法,此题可以用线段树,可以用树状数组
其实这题求的都是下面的和左面的,线段树这种数组结构刚好可以满足,为什么呢?这里稍微解释下吧,也有助于以后的复习
看上面这个图,[1,1],[2,2]这样的叶节点表示题目的的图中的最下一层,而[4,5],[1,3]这样节点的value值是是其子节点之和,多以可以理解为在二维坐标系中是高于下面的节点的,其子节点都在它的左面,可能说的比较模糊,我也是想一会就明白了
1 #include<iostream> 2 #include<fstream> 3 4 using namespace std; 5 6 struct e{ 7 int l,r; 8 int cn; 9 }tree[70000]; 10 int level[15001]; 11 int n; 12 int x[15001],y[15001]; 13 int maxx; 14 15 void build(int l,int r,int p) 16 { 17 tree[p].l=l; 18 tree[p].r=r; 19 tree[p].cn=0; 20 if(l<r) 21 { 22 int mid=(l+r)>>1; 23 build(l,mid,p*2); 24 build(mid+1,r,p*2+1); 25 } 26 } 27 28 void insert(int l,int p) 29 { 30 if(l==tree[p].l&&l==tree[p].r) 31 { 32 tree[p].cn++; 33 return; 34 } 35 int mid=(tree[p].l+tree[p].r)>>1; 36 if(l<=mid) 37 insert(l,p*2); 38 else 39 insert(l,p*2+1); 40 tree[p].cn++; 41 } 42 43 int find(int l,int r,int p) 44 { 45 if(l==tree[p].l&&r==tree[p].r) 46 { 47 return tree[p].cn; 48 } 49 int mid=(tree[p].l+tree[p].r)>>1; 50 if(r<=mid) 51 return find(l,r,2*p); 52 if(l>mid) return find(l,r,2*p+1); 53 else 54 return find(l,mid,2*p)+find(mid+1,r,2*p+1); 55 } 56 57 58 void read() 59 { 60 // ifstream cin("in.txt"); 61 int i,j,k; 62 cin>>n; 63 for(i=1;i<=n;i++) 64 { 65 cin>>x[i]>>y[i]; 66 maxx=max(maxx,x[i]); 67 } 68 build(0,maxx,1); 69 for(i=1;i<=n;i++) 70 { 71 level[find(0,x[i],1)]++; 72 insert(x[i],1); 73 } 74 for(i=0;i<n;i++) 75 cout<<level[i]<<endl; 76 } 77 78 int main() 79 { 80 read(); 81 return 0; 82 }
c++的输入输出是不行的,必须要用c的,否则过不了