权值线段树 洛谷1168

这道题好像不止权值线段树一个做法;

不过本人是用权值线段树来解的,由于数据开到了1e9,所以得离散化。

离散化之后,先build,记录每一个节点的所包含的数字大小范围,

然后在慢慢建树,建树的过程中,当单数的时候,就进行查询;

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<math.h>
 4 #include<string.h>
 5 #include<queue>
 6 using namespace std;
 7 const int maxn=1e5+10;
 8 int a[maxn],b[maxn];
 9 struct node
10 {
11     int l,r,mid;
12     int num;
13 }tree[maxn<<2];
14 void build(int l,int r,int cur)
15 {
16     tree[cur].l=l,tree[cur].r=r;
17     tree[cur].num=0;
18     tree[cur].mid=(l+r)/2;
19     if(l==r) return;
20     build(l,tree[cur].mid,cur<<1);
21     build(tree[cur].mid+1,r,cur<<1|1);
22 }
23 void update(int pos,int cur)
24 {
25     tree[cur].num++;
26     if(tree[cur].l==tree[cur].r) return;
27     if(pos<=tree[cur].mid)
28         update(pos,cur<<1);
29     else update(pos,cur<<1|1);
30 }
31 int query(int base,int cur)
32 {
33     if(tree[cur].l==tree[cur].r) return tree[cur].l;
34     if(base<=tree[cur<<1].num) return (query(base,cur<<1));
35     else return (query(base-tree[cur<<1].num,cur<<1|1));
36 }
37 int main()
38 {
39     int n;
40     scanf("%d",&n);
41     for(int i=1;i<=n;i++){
42         scanf("%d",&a[i]);
43         b[i]=a[i];
44     }
45     sort(b+1,b+1+n);
46     int t=unique(b+1,b+1+n)-b-1;
47     build(1,n,1);
48     for(int i=1;i<=n;i++){
49         int pos=lower_bound(b+1,b+1+t,a[i])-b;
50         update(pos,1);
51         if(i%2) printf("%d\n",b[query(i/2+1,1)]);
52     }
53     return 0;
54 }

猜你喜欢

转载自www.cnblogs.com/pangbi/p/11517527.html
今日推荐