首页 > 代码库 > HDU 4973
HDU 4973
一个线段树问题
节点记录这样几个值,sum(这个区间的总和),best(这个区间中的最大值),lazy(翻倍的lazy标记)
这里的[a,b]区间代表数为a与b之间的那些东西,因为无论怎么弄这些相同数字的都是连续的
1 #include <set> 2 #include <map> 3 #include <queue> 4 #include <deque> 5 #include <cmath> 6 #include <vector> 7 #include <string> 8 #include <cstdio> 9 #include <cstdlib> 10 #include <cstring> 11 #include <cassert> 12 #include <iostream> 13 #include <algorithm> 14 15 using namespace std; 16 17 typedef long long LL; 18 typedef pair <int, int> PII; 19 20 const int N = 5e4 + 7; 21 const int INF = 0x3f3f3f3f; 22 const int MOD = 1e9 + 7; 23 const double EPS = 1e-12; 24 const double PI = acos(0) * 2; 25 26 struct Node{ 27 int a, b, lazy; 28 LL sum, best; 29 Node *l, *r; 30 }; 31 32 struct SegmentTree{ 33 Node tree[N << 1], *root; 34 int pos; 35 36 Node *build(int a, int b){ 37 Node *root = &tree[++pos]; 38 root->a = a; 39 root->b = b; 40 root->sum = b - a + 1; 41 root->best = 1; 42 root->lazy = 0; 43 if (a == b) 44 return root; 45 int mid = (a + b) >> 1; 46 root->l = build(a, mid); 47 root->r = build(mid + 1, b); 48 return root; 49 } 50 51 void init(int n){ 52 pos = 0; 53 root = build(1, n); 54 } 55 56 void release(Node *root){ 57 if (root->lazy){ 58 root->l->sum <<= root->lazy; 59 root->l->best <<= root->lazy; 60 root->l->lazy += root->lazy; 61 root->r->sum <<= root->lazy; 62 root->r->best <<= root->lazy; 63 root->r->lazy += root->lazy; 64 root->lazy = 0; 65 } 66 } 67 68 void update(Node *root){ 69 root->sum = root->l->sum + root->r->sum; 70 root->best = max(root->l->best, root->r->best); 71 } 72 73 void insert(Node *root, LL a, LL b){ 74 //printf("Insert [%d, %d] of %I64d %I64d\n", root->a, root->b, a, b); 75 if (root->a == root->b){ 76 root->sum += b - a + 1; 77 root->best = root->sum; 78 return; 79 } 80 if (root->sum == b - a + 1){ 81 root->sum <<= 1; 82 root->best <<= 1; 83 ++root->lazy; 84 return; 85 } 86 release(root); 87 LL left = root->l->sum; 88 if (left >= a) 89 insert(root->l, a, min(left, b)); 90 if (left < b) 91 insert(root->r, max(a - left, 1LL), b - left); 92 update(root); 93 } 94 95 void add(LL l, LL r){ 96 insert(root, l, r); 97 } 98 99 LL find(Node *root, LL a, LL b){100 if (root->a == root->b){101 return b - a + 1;102 }103 if (root->sum == b - a + 1){104 return root->best;105 }106 release(root);107 LL ret = 0;108 if (root->l->sum >= a)109 ret = max(ret, find(root->l, a, min(root->l->sum, b)));110 if (root->l->sum < b)111 ret = max(ret, find(root->r, max(a - root->l->sum, 1LL), b - root->l->sum));112 //update(root);113 return ret;114 }115 116 LL query(LL l, LL r){117 return find(root, l, r);118 }119 120 void debug(){121 for (int i = 1; i <= pos; ++i)122 printf("%d - %d : sum %I64d best %I64d lazy %d\n", tree[i].a, tree[i].b, tree[i].sum, tree[i].best, tree[i].lazy);123 }124 }tree;125 126 int main(){127 //freopen("a.in", "r", stdin);128 //freopen("a.out", "w", stdout);129 int T, n, m;130 char op[10];131 LL x, y;132 scanf("%d", &T);133 for (int Test = 1; Test <= T; ++Test){134 scanf("%d%d", &n, &m);135 tree.init(n);136 //tree.debug();137 printf("Case #%d:\n", Test);138 for (int i = 1; i <= m; ++i){139 scanf(" %s%I64d%I64d", op, &x, &y);140 if (op[0] == ‘D‘)141 tree.add(x, y);142 else143 printf("%I64d\n", tree.query(x, y));144 //tree.debug();145 }146 }147 148 return 0;149 }
HDU 4973
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。