标签:插入 ace 思路 arc ssi arch icpc length ext
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7265 Accepted Submission(s): 3127
1 //2017-09-07 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #define ll long long 7 #define mid ((l+r)>>1) 8 9 using namespace std; 10 11 const int N = 100010; 12 const int M = N * 30; 13 struct node{ 14 int lson, rson, sum;//sum维护l到r的数有几个 15 }tree[M]; 16 //第i棵线段树为插入前i个数字所构成的权值线段树。 17 int root[N], arr[N], arr2[N], tot; 18 int n, m, q; 19 20 void init(){//将原数列排序并去重 21 tot = 0; 22 for(int i = 1; i <= n; i++) 23 arr2[i] = arr[i]; 24 sort(arr2+1, arr2+1+n); 25 m = unique(arr2+1, arr2+1+n)-arr2-1; 26 } 27 28 //离散化 29 int getID(int x){ 30 return lower_bound(arr2+1, arr2+1+m, x) - arr2; 31 } 32 33 int build(int l, int r){ 34 int id = ++tot; 35 tree[id].sum = 0; 36 if(l == r)return id; 37 if(l <= mid) 38 tree[id].lson = build(l, mid); 39 if(r > mid) 40 tree[id].rson = build(mid+1, r); 41 return id; 42 } 43 44 int update(int id, int pos, int value){ 45 int newroot = ++tot, tmp = newroot; 46 tree[newroot].sum = tree[id].sum + value; 47 int l = 1, r = m; 48 while(l < r){ 49 if(pos <= mid){ 50 tree[newroot].lson = ++tot; 51 tree[newroot].rson = tree[id].rson; 52 newroot = tree[newroot].lson; 53 id = tree[id].lson; 54 r = mid; 55 }else{ 56 tree[newroot].rson = ++tot; 57 tree[newroot].lson = tree[id].lson; 58 newroot = tree[newroot].rson; 59 id = tree[id].rson; 60 l = mid+1; 61 } 62 tree[newroot].sum = tree[id].sum + value; 63 } 64 return tmp; 65 } 66 67 int query(int ltree, int rtree, int k){ 68 int l = 1, r = m, ans = 0; 69 while(l < r){ 70 if(k <= mid){ 71 ltree = tree[ltree].lson; 72 rtree = tree[rtree].lson; 73 r = mid; 74 }else{ 75 ans += tree[tree[rtree].lson].sum - tree[tree[ltree].lson].sum; 76 ltree = tree[ltree].rson; 77 rtree = tree[rtree].rson; 78 l = mid+1; 79 } 80 } 81 if(l == r){ 82 if(k < l)return 0; 83 else return ans + tree[rtree].sum - tree[ltree].sum; 84 } 85 } 86 87 int main() 88 { 89 //freopen("dataN.txt", "r", stdin); 90 int T, kase = 0; 91 scanf("%d", &T); 92 while(T--){ 93 scanf("%d%d", &n, &q); 94 for(int i = 1; i <= n; i++) 95 scanf("%d", &arr[i]); 96 init(); 97 root[0] = build(1, m); 98 for(int i = 1; i <= n; i++){ 99 int pos = getID(arr[i]); 100 root[i] = update(root[i-1], pos, 1); 101 } 102 printf("Case %d:\n", ++kase); 103 while(q--){ 104 int l, r, h; 105 scanf("%d%d%d", &l, &r, &h); 106 l++; r++; 107 int pos = getID(h);//找到第一个小于概数的位置 108 if(arr2[pos] > h)pos--; 109 printf("%d\n", query(root[l-1], root[r], pos)); 110 } 111 } 112 113 return 0; 114 }
HDU4417(SummerTrainingDay08-N 主席树)
标签:插入 ace 思路 arc ssi arch icpc length ext
原文地址:http://www.cnblogs.com/Penn000/p/7492171.html