程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu 4417 Super Mario/樹套樹,hdu4417

hdu 4417 Super Mario/樹套樹,hdu4417

編輯:C++入門知識

hdu 4417 Super Mario/樹套樹,hdu4417


原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4417

題意很簡單,給定一個序列求一個區間 [L, R,]中小於等於H的元素的個數。

好像函數式線段樹可解吧,可弱弱的沙茶一直沒弄懂其精髓,只好用樹套樹暴力碾壓了敲打

額樹套樹,線段樹的每一個節點套一個sb樹。

當查詢[l,r]區間中的值小於等於H的個數,先用線段樹找到相應的區間,

然後再查詢該區間下對應的平衡樹中小於等於H的個數,累加即可。

一直以為會超時,結果400+ms就過了,數據應該很弱吧(自己對拍了一組(N,M)10w規模的跑了2s多o(╯□╰)o)。

1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 #define lc root<<1 6 #define rc root<<1|1 7 const int Max_N = 100100; 8 struct SBT{ 9 int v, s, c; 10 SBT *ch[2]; 11 inline void set(int _v = 0){ 12 v = _v, c = s = 1; 13 ch[0] = ch[1] = null; 14 } 15 inline void push_up(){ 16 s = ch[0]->s + ch[1]->s + c; 17 } 18 inline int cmp(int x) const{ 19 return v == x ? -1 : x > v; 20 } 21 }*null, stack[Max_N << 3], *ptr[Max_N << 2]; 22 int sz = 0, sum = 0, arr[Max_N]; 23 void init(){ 24 null = &stack[sz++]; 25 null->v = null->s = null->c = 0; 26 } 27 inline void rotate(SBT* &x, int d){ 28 SBT *k = x->ch[!d]; 29 x->ch[!d] = k->ch[d]; 30 k->ch[d] = x; 31 k->s = x->s;; 32 x->push_up(); 33 x = k; 34 } 35 void Maintain(SBT* &x, int d){ 36 if (x->ch[d] == null) return; 37 if (x->ch[d]->ch[d]->s > x->ch[!d]->s){ 38 rotate(x, !d); 39 } else if (x->ch[d]->ch[!d]->s > x->ch[d]->s){ 40 rotate(x->ch[d], d), rotate(x, !d); 41 } else { 42 return; 43 } 44 Maintain(x, 0), Maintain(x, 1); 45 } 46 void insert(SBT* &x, int v){ 47 if (x == null){ 48 x = &stack[sz++]; 49 x->set(v); 50 } else { 51 x->s++; 52 int d = x->cmp(v); 53 if (-1 == d){ 54 x->c++; 55 return; 56 } 57 insert(x->ch[d], v); 58 x->push_up(); 59 Maintain(x, d); 60 } 61 } 62 int sbt_rank(SBT *x, int key){ 63 int t, cur; 64 for (t = cur = 0; x != null;){ 65 t = x->ch[0]->s; 66 if (key < x->v) x = x->ch[0]; 67 else if (key >= x->v) cur += x->c + t, x = x->ch[1]; 68 } 69 return cur; 70 } 71 void seg_built(int root, int l, int r){ 72 ptr[root] = null; 73 for (int i = l; i <= r; i++) insert(ptr[root], arr[i]); 74 if (l == r) return; 75 int mid = (l + r) >> 1; 76 seg_built(lc, l, mid); 77 seg_built(rc, mid + 1, r); 78 } 79 void seg_rank(int root, int l, int r, int x, int y, int v){ 80 if (x > r || y < l) return; 81 if (x <= l && y >= r){ 82 sum += sbt_rank(ptr[root], v); 83 return; 84 } 85 int mid = (l + r) >> 1; 86 seg_rank(lc, l, mid, x, y, v); 87 seg_rank(rc, mid + 1, r, x, y, v); 88 } 89 int main(){ 90 #ifdef LOCAL 91 freopen("in.txt", "r", stdin); 92 freopen("out.txt", "w+", stdout); 93 #endif 94 int i, t, n, m, a, b, c, k = 1; 95 scanf("%d", &t); 96 while (t--){ 97 sz = 0, init(); 98 scanf("%d %d", &n, &m); 99 printf("Case %d:\n", k++); 100 for (i = 1; i <= n; i++) scanf("%d", &arr[i]); 101 seg_built(1, 1, n); 102 while (m--){ 103 scanf("%d %d %d", &a, &b, &c); 104 sum = 0; 105 seg_rank(1, 1, n, a + 1, b + 1, c); 106 printf("%d\n", sum); 107 } 108 } 109 return 0; 110 } View Code

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved