【HDU 4973 多校联合】A simple simulation problem【树状数组】
2014-08-21 17:59
274 查看
题意:给出n个数字,分别是1-n。m次操作,有两种操作Q l r, D l r,1.查询区间【l,r】中最多相同数字的个数。2.把【l,r】中的数字都复制一个,如:1 2 3 -> 1 1 2 2 3 3
思路:我们利用cnt[i]数组记录数列中i的个数,然后用树状数组记录前缀和。对于每次Q的操作,我们对于l,r两个端点在前缀和数组中进行二分查找,就可以知道l,r分别是哪个数字,然后通过cnt数字就可以知道落在这个区间中的数目,相应的D操作也是这样子,进行增加个数。
思路:我们利用cnt[i]数组记录数列中i的个数,然后用树状数组记录前缀和。对于每次Q的操作,我们对于l,r两个端点在前缀和数组中进行二分查找,就可以知道l,r分别是哪个数字,然后通过cnt数字就可以知道落在这个区间中的数目,相应的D操作也是这样子,进行增加个数。
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define N 50004 typedef long long ll; ll sum , cnt ; int n, m; int lb(int k) {return k&(-k);} ll getsum(int k) { ll re = 0; while (k > 0) { re += sum[k]; k -= lb(k); } return re; } void add(int k, ll v) { while (k <= n) { sum[k] += v; k += lb(k); } } int find(ll v) { int f = 1, r = n, mid; ll tm; while (f < r) { mid = f+r>>1; ll tm = getsum(mid); if (tm < v) f = mid+1; else r = mid; } return f; } void update(ll l, ll r) { int i, L = find(l), R = find(r); if (L == R) { add(L, r-l+1); cnt[L] += r-l+1; return; } ll tm = getsum(L), tp = getsum(R-1) ; add(L, tm-l+1), add(R, r-tp); cnt[L] += tm-l+1;cnt[R] += r-tp; for (i = L+1;i < R;i++) { add(i, cnt[i]); cnt[i] += cnt[i]; } } ll cal(ll l, ll r) { int i, L = find(l), R = find(r); ll tm, re = 0, tl = l, tp; if (L == R) return r-l+1; re = max(re, getsum(L)-l+1); re = max(re, r-getsum(R-1)); for (i = L+1;i < R;i++) { if (re < cnt[i]) re = cnt[i]; } return re; } int main() { int T, ca = 1, i; char op; ll l, r; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); for (i = 0;i <= n;i++) sum[i] = cnt[i] = 0; for (i = 1;i <= n;i++) add(i, 1), cnt[i] = 1; printf("Case #%d:\n", ca++); while (m--) { scanf(" %c%I64d%I64d", &op, &l, &r); if (op == 'D') { update(l, r); }else { printf("%I64d\n", cal(l, r)); } } } }
相关文章推荐
- hdu 4973 A simple simulation problem (多校第10场 线段树)
- hdu 4973 A simple simulation problem.(线段树)
- HDU-4973-A simple simulation problem.(线段树)
- hdu 4267 A Simple Problem with Integers(分类别维护多个树状数组)
- hdu 4973 A simple simulation problem 线段树
- HDU 4267 A Simple Problem with Integers【树状数组】
- HDU 4267 - A Simple Problem with Integers 树状数组区间修改
- A Simple Problem with Integers 多树状数组分割,区间修改,单点求职。 hdu 4267
- hdu 4973 A simple simulation problem 2014 Multi-University Training Contest 10
- HDU 4973 A simple simulation problem. 线段树
- 【三维树状数组与离散化】HDU 4267——A Simple Problem with Integers
- hdu 4973 A simple simulation problem. (线段树)
- HDU 4973 A simple simulation problem.(线段树)
- hdu 4973 A simple simulation problem.---线段树
- HDU 4267 A Simple Problem with Integers(树状数组)
- hdu 4973 A simple simulation problem.(2014 Multi-University Training Contest 10)
- 【HDU】4973 A simple simulation problem. 线段树
- hdu 4973 A simple simulation problem 线段树 2014 Multi-University Training Contest 10-1003
- HDU 4267 A Simple Problem with Integers 多个树状数组
- hdu - 4973 - A simple simulation problem.(线段树单点更新 + 区间更新)