标签:
Vijos1448校门外的树 题解
1 #include "bits/stdc++.h" 2 #define maxN 50010 3 4 using namespace std ; 5 typedef long long QAQ ; 6 7 struct Tree 8 { 9 int l , r ; 10 QAQ liml , limr ;//左括号右括号 11 }; 12 13 Tree tr[maxN << 2]; 14 15 void Build_Tree ( int x , int y , int i )//建树 16 { 17 tr[i].l = x ; 18 tr[i].r = y ; 19 if( x == y )return ; 20 else 21 { 22 QAQ mid = (tr[i].l + tr[i].r) >> 1 ; 23 Build_Tree ( x , mid , i << 1); 24 Build_Tree ( mid + 1 , y , i << 1 | 1); 25 return ; 26 } 27 } 28 29 void Update_left ( int w , int i ) 30 { 31 if( w == tr[i].l && w == tr[i].r )tr[i].liml++;//找到目标节点 32 else 33 { 34 QAQ mid = (tr[i].l + tr[i].r) >> 1 ; 35 if( w > mid )Update_left( w , i << 1 | 1);//找右儿子 36 else if( w <= mid)Update_left( w , i << 1 );//找左儿子 37 tr[i].liml = tr[i << 1].liml + tr[i << 1 | 1].liml ;//回溯更新 38 } 39 } 40 41 void Update_right ( int w , int i )//同Update_left 42 { 43 if( w == tr[i].l && w == tr[i].r )tr[i].limr++; 44 else 45 { 46 QAQ mid = (tr[i].l + tr[i].r) >> 1 ; 47 if( w > mid )Update_right( w , i << 1 | 1); 48 else if( w <= mid)Update_right( w , i << 1 ); 49 tr[i].limr = tr[i << 1].limr + tr[i << 1 | 1].limr ; 50 } 51 } 52 53 QAQ Query_left ( int q , int w , int i )//同Query_right 54 { 55 if( q <= tr[i].l && w >= tr[i].r )return tr[i].liml ; 56 else 57 { 58 QAQ mid = (tr[i].l + tr[i].r) >> 1 ; 59 if ( q > mid )return Query_left ( q , w , i << 1 | 1); 60 else if ( w <= mid ) return Query_left ( q , w , i << 1); 61 else return Query_left ( q , w , i << 1 | 1) + Query_left ( q , w , i << 1); 62 } 63 } 64 65 QAQ Query_right ( int q , int w , int i ) 66 { 67 if( q <= tr[i].l && w >= tr[i].r )return tr[i].limr ;//找到目标区间直接返回 68 else 69 { 70 QAQ mid = (tr[i].l + tr[i].r) >> 1 ; 71 if ( q > mid )return Query_right ( q , w , i << 1 | 1);//找右儿子 72 else if ( w <= mid ) return Query_right ( q , w , i << 1);//找左儿子 73 else return Query_right ( q , w , i << 1 | 1) + Query_right ( q , w , i << 1);//左右儿子都查找 74 } 75 } 76 77 int main() 78 { 79 int N, M, op, ll, rr ; 80 scanf("%d %d", &N, &M); 81 Build_Tree ( 1 , N , 1 ) ;//建树 82 while(M--) 83 { 84 scanf("%d%d%d", &op, &ll, &rr); 85 if( op == 1 ) 86 { 87 Update_left ( ll , 1);//添加左括号 88 Update_right ( rr , 1 );//添加右括号 89 } 90 else 91 { 92 QAQ ans = Query_left( 1 , rr , 1); 93 if (ll != 1)ans -= Query_right(1 , ll - 1 , 1);//当ll不等于1时再相减,否则栈会炸 94 printf("%I64d\n", ans); 95 } 96 } 97 return 0 ; 98 }
标签:
原文地址:http://www.cnblogs.com/shadowland/p/5870395.html