poj(2325)线段树

这里介绍另外一种解法,此题可以用线段树,可以用树状数组

其实这题求的都是下面的和左面的,线段树这种数组结构刚好可以满足,为什么呢?这里稍微解释下吧,也有助于以后的复习

看上面这个图,[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的,否则过不了

posted on 2012-08-08 20:38  矮人狙击手!  阅读(368)  评论(0)    收藏  举报

导航