标签:nod ini www 怎么 实现 iostream += app max
1、主席树是可持久化线段树
2、可持久化技术用于将多棵树相同的部分复用、不同的部分分开构成一颗新树。
3、主席树的实际物理原型是多颗线段树。
1、设计上应当考虑,如果有了多颗线段树,应当怎么做这道题?
2、有了思路之后应当考虑,可持久化线段树的性质是什么样的,使得我们应当如何针对这种特殊的性质完成线段树的设计?
3、如何进行更新操作?
ans:
1、如果有多颗线段树,则每次插入新的元素建立一颗的线段树;在查找的时候,可以知道对于任意元素,有多少个元素小于等于给定元素。
2、想象可得,每个点的更新都将造成从最底部到根节点的一系列改变。因此,可得:根节点必然每次改变,且新的更节点可以带出新的其余替换节点。
3、考虑使用上一次的根节点的若干节点,在一路向下的过程中不断进行节点复制。这种写法可以相对优雅的完成主席树的更新。
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1175
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 5 #define ll long long 6 #define idx(x) (lower_bound(mapp,mapp+n,x)-mapp) 7 8 9 const ll MAXN=1<<20; 10 11 int head[50233]; 12 int n,m; 13 class Node 14 { 15 public: 16 int l,r,number,lc,rc; 17 18 };Node tree[MAXN]; 19 int tree_cnt ; 20 int mapp[50233]; 21 int arr[50233]; 22 23 void build(int a,int b,int now) 24 { 25 tree_cnt ++ ; 26 tree[now].l = a; 27 tree[now].r = b; 28 tree[now].number = 0; 29 if(a == b-1)return ; 30 int mid = (a+b)/2; 31 tree[now].lc = tree_cnt; 32 build(a,mid,tree_cnt); 33 tree[now].rc = tree_cnt; 34 build(mid,b,tree_cnt); 35 } 36 37 void insert(int pos,int key,int times,int old) 38 { 39 40 int now = tree_cnt++; 41 int l = tree[old].l; 42 int r = tree[old].r; 43 44 tree[now].l = l; 45 tree[now].r = r; 46 tree[now].number = tree[old].number; 47 if(l == r-1) 48 { 49 tree[now].number += key; 50 return ; 51 } 52 int mid = (l+r)/2; 53 54 tree[now].lc = tree[old].lc; 55 tree[now].rc = tree[old].rc; 56 if(pos < mid) 57 { 58 tree[now].lc = tree_cnt; 59 insert(pos,key,times,tree[old].lc); 60 }else{ 61 tree[now].rc = tree_cnt; 62 insert(pos,key,times,tree[old].rc); 63 } 64 tree[now].number = tree[tree[now].lc].number + tree[tree[now].rc].number; 65 return ; 66 } 67 68 int search(int pos,int now) 69 { 70 int l = tree[now].l; 71 int r = tree[now].r; 72 if(l == r-1)return tree[now].number; 73 int mid = (l+r)/2; 74 int lc = tree[now].lc; 75 int rc = tree[now].rc; 76 if(mid <= pos)return tree[lc].number+search(pos,rc); 77 else return search(pos,lc); 78 } 79 80 int check(int a,int b,int num) 81 { 82 int cntt = search(num,head[b+1]); 83 cntt -= search(num,head[a]); 84 return cntt; 85 } 86 87 int bin_search(int a,int b,int l,int r,int num) 88 { 89 if(l == r-1)return mapp[r]; 90 int mid = (l+r)/2; 91 int cntt = check(a,b,mid); 92 if(cntt<num)return bin_search(a,b,mid,r,num); 93 else return bin_search(a,b,l,mid,num); 94 } 95 96 void init() 97 { 98 tree_cnt = 1; 99 head[0] = 1; 100 build(0,n,1); 101 for(int i=0;i<n;++i) 102 { 103 cin>>arr[i]; 104 mapp[i] = arr[i]; 105 }sort(mapp,mapp+n); 106 cin>>m; 107 for(int i=0;i<n;++i) 108 { 109 head[i+1] = tree_cnt; 110 insert(idx(arr[i]),1,i+1,head[i]); 111 } 112 for(int i=0;i<m;++i) 113 { 114 int a,b,c; 115 cin>>a>>b>>c; 116 cout<<bin_search(a,b,-1,n,b-a+2-c)<<"\n"; 117 } 118 } 119 int main() 120 { 121 cin.sync_with_stdio(false); 122 while(cin>>n)init(); 123 // build(0,233,1); 124 125 return 0; 126 }
标签:nod ini www 怎么 实现 iostream += app max
原文地址:https://www.cnblogs.com/rikka/p/9162086.html