hdu4973
来源:互联网 发布:java的mvc框架 编辑:程序博客网 时间:2024/06/05 23:50
线段树,每个点记录该点出现的次数,对于l,r的更新,
找到l所对应的数,找到r对应的数,单点更新这两个数,然后区间更新他们之间的数。
查找也是一样。
#include <cstdio>#include <cstring>#define max(a, b) ((a) > (b)) ? (a) : (b)#define min(a, b) ((a) > (b)) ? (b) : (a)const int maxn = 400007;struct Seg { int left, right; int lazy; long long max_num, sum;};struct Seg seg[maxn * 4];void pushUp(int order) { seg[order].max_num = max(seg[order * 2].max_num, seg[order * 2 + 1].max_num); seg[order].sum = seg[order * 2].sum + seg[order * 2 + 1].sum;}void pushDown(int order) { if (seg[order].lazy > 1) { seg[order * 2].sum *= seg[order].lazy; seg[order * 2 + 1].sum *= seg[order].lazy; seg[order * 2].max_num *= seg[order].lazy; seg[order * 2 + 1].max_num *= seg[order].lazy; seg[order * 2].lazy *= seg[order].lazy; seg[order * 2 + 1].lazy *= seg[order].lazy; seg[order].lazy = 1; }}void init(int order, int left, int right) { int mid = (left + right) >> 1; seg[order].left = left; seg[order].right = right; seg[order].lazy = 1; if (left == right) { seg[order].max_num = 1; seg[order].sum = 1; return ; } init(order * 2, left, mid); init(order * 2 + 1, mid + 1, right); pushUp(order);}void update(int order, int left, int right) { if (right < left) { return ; } int mid = (seg[order].left + seg[order].right) >> 1; if (left <= seg[order].left && right >= seg[order].right) { seg[order].lazy *= 2; seg[order].sum *= 2; seg[order].max_num *= 2; return ; } pushDown(order); if (right <= mid) { update(order * 2, left, right); } else if (left > mid) { update(order * 2 + 1, left, right); } else { update(order * 2, left, mid); update(order * 2 + 1, mid + 1, right); } pushUp(order);}long long querySum(int order, int left, int right) { if (right < left) { return 0; } int mid = (seg[order].left + seg[order].right) >> 1; if (left <= seg[order].left && right >= seg[order].right) { return seg[order].sum; } pushDown(order); if (right <= mid) { return querySum(order * 2, left, right); } else if (left > mid) { return querySum(order * 2 + 1, left, right); } else { return querySum(order * 2, left, mid) + querySum(order * 2 + 1, mid + 1, right); }}long long query(int order, int left, int right) { if (right < left) { return 0; } int mid = (seg[order].left + seg[order].right) >> 1; if (left <= seg[order].left && right >= seg[order].right) { return seg[order].max_num; } pushDown(order); if (right <= mid) { return query(order * 2, left, right); } else if (left > mid) { return query(order * 2 + 1, left, right); } else { long long max_1 = query(order * 2, left, mid); long long max_2 = query(order * 2 + 1, mid + 1, right); if (max_1 > max_2) { return max_1; } else { return max_2; } }}void updateSingle(int order, int loc, long long val) { int mid = (seg[order].left + seg[order].right) >> 1; if (seg[order].left == seg[order].right) { seg[order].sum += val; seg[order].max_num += val; return ; } pushDown(order); if (loc <= mid) { updateSingle(order * 2, loc, val); } else { updateSingle(order * 2 + 1, loc, val); } pushUp(order);}int findLoc(int order, long long val) { if (seg[order].left == seg[order].right) { return order; } pushDown(order); if (val > seg[order * 2].sum) { return findLoc(order * 2 + 1, val - seg[order * 2].sum); } else { return findLoc(order * 2, val); }}int n, m;int main() {// freopen("in.txt", "r", stdin); int test_case; int ncase = 1; scanf("%d", &test_case); while (test_case--) { printf("Case #%d:\n", ncase); ncase++; scanf("%d%d", &n, &m); init(1, 1, n); for (int i = 1; i <= m; i++) { char temp[10]; long long l, r; scanf("%s", temp); scanf("%I64d%I64d", &l, &r); int order_1 = findLoc(1, l); int order_2 = findLoc(1, r); if (temp[0] == 'D') { if (order_1 == order_2) { updateSingle(1, seg[order_1].left, r - l + 1); } else { long long pre_sum = querySum(1, 1, seg[order_1].left); long long temp = querySum(1, 1, seg[order_2].left - 1); updateSingle(1, seg[order_1].left, pre_sum - l + 1); updateSingle(1, seg[order_2].left, r - temp); update(1, seg[order_1].left + 1, seg[order_2].left - 1); } } else { long long ans = 0; if (order_1 == order_2) { ans = (r - l + 1); } else { long long pre_sum = querySum(1, 1, seg[order_1].left); ans = pre_sum - l + 1; pre_sum = querySum(1, 1, seg[order_2].left - 1); ans = max(ans, r - pre_sum); pre_sum = query(1, seg[order_1].left + 1, seg[order_2].left - 1); ans = max(ans, pre_sum); } printf("%I64d\n", ans); } } } return 0;}
0 0
- hdu4973
- HDU4973 【几何。】
- hdu4973(线段树)
- hdu4973 线段树
- hdu4973 线段树
- HDU4973 A simple simulation problem.
- HDU4973 A simple simulation problem
- hdu4973 A simple simulation problem. 线段树
- HDU4973:A simple simulation problem.(线段树)
- hdu4973 A simple simulation problem.(多校第十场1003)
- hdu4973 线段树(题目不错,用了点,段,更新查找还有DFS)
- 线段树单点更新+成段更新(好)hdu4973(多校联合)
- 2014多校10(1003)hdu4973(简单线段树区间操作)
- hdu4973 A simple simulation problem.(成段更新+下标转化)
- 去掉文件中^M的方法
- hdu 4960 Another OCD Patient dp
- 跨服务器操作数据库
- PHP盛宴——常用函数集锦
- 1408211934-hd-Crixalis's Equipment.cpp
- hdu4973
- POJ 1459 Power Network
- Ubuntu上编译安装Freetype/Freetype-py
- 韩语学习之第十一课
- svn代码回滚命令
- HDU 4960 Another OCD Patient(DP)
- Candy
- MySQL 数据类型
- HDU 3549 Flow Problem