【BZOJ 3050】【USACO2013 Jan】Seating 线段树
2016-03-30 11:25
417 查看
线段树维护4个标记,
昨天互测时题意理解错了,今天上午才发现。
4个标记维护区间内奶牛个数,左端最长连续空位,右端最长连续空位,区间内最长连续空位,然后就没了。
昨天互测时题意理解错了,今天上午才发现。
#include<cstdio> #include<cstring> #include<algorithm> #define N 500003 using namespace std; int sum[N*3], n, m, ans = 0, lazy[N*3],left[N*3],right[N*3],whole[N*3]; inline void buildtree(int l, int r, int rt) { sum[rt] = 0; lazy[rt] = 0; left[rt] = r - l + 1; right[rt] = r - l + 1; whole[rt] = r - l + 1; if (l == r) return; int mid = (l + r) >> 1; buildtree(l, mid, rt << 1); buildtree(mid + 1, r, rt << 1 | 1); } inline void pushdown(int l, int r, int rt) { if (lazy[rt] != 0) { if (lazy[rt] == 1) { lazy[rt] = 0; lazy[rt << 1] = 1; lazy[rt << 1 | 1] = 1; int mid = (l + r) >> 1; sum[rt << 1] = mid - l + 1; left[rt << 1] = 0; right[rt << 1] = 0; whole[rt << 1] = 0; sum[rt << 1 | 1] = r - mid; left[rt << 1 | 1] = 0; right[rt << 1 | 1] = 0; whole[rt << 1 | 1] = 0; } else { lazy[rt] = 0; lazy[rt << 1] = -1; lazy[rt << 1 | 1] = -1; int mid = (l + r) >> 1; sum[rt << 1] = 0; left[rt << 1] = mid - l + 1; right[rt << 1] = mid - l + 1; whole[rt << 1] = mid - l + 1; sum[rt << 1 | 1] = 0; left[rt << 1 | 1] = r - mid; right[rt << 1 | 1] = r - mid; whole[rt << 1 | 1] = r - mid; } } } inline void pushup(int rt){ sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; left[rt] = sum[rt << 1] == 0 ? whole[rt << 1] + left[rt << 1 | 1] : left[rt << 1]; right[rt] = sum[rt << 1 | 1] == 0 ? whole[rt << 1 | 1] + right[rt << 1] : right[rt << 1 | 1]; whole[rt] = max(whole[rt << 1], whole[rt << 1 | 1]); whole[rt] = max(whole[rt], right[rt << 1] + left[rt << 1 | 1]); } inline void clr(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) { sum[rt] = 0; left[rt] = r - l + 1; right[rt] = r - l + 1; whole[rt] = r - l + 1; lazy[rt] = -1; return; } pushdown(l, r, rt); int mid = (l + r) >> 1; if (L <= mid) clr(L, R, l, mid, rt << 1); if (R > mid) clr(L, R, mid + 1, r, rt << 1 | 1); pushup(rt); } inline void put(int L, int R, int l, int r, int rt) { if (L <=l && r <= R) { sum[rt] = r - l + 1; left[rt] = 0; right[rt] = 0; whole[rt] = 0; lazy[rt] = 1; return; } pushdown(l, r, rt); int mid = (l + r) >> 1; if (L <= mid) put(L, R, l, mid, rt << 1); if (R > mid) put(L, R, mid + 1, r, rt << 1 | 1); pushup(rt); } inline void add(int num, int l, int r, int rt) { if (l == r) { put(l, r, 1, n, 1); return; } int mid = (l + r) >> 1; if (whole[rt << 1] >= num) add(num, l, mid, rt << 1); else if (right[rt << 1] + left[rt << 1 | 1] >= num) put(mid + 1 - right[rt << 1], mid - right[rt << 1] + num, 1, n, 1); else add(num, mid + 1, r, rt << 1 | 1); } int main() { scanf("%d%d\n", &n, &m); buildtree(1, n, 1); char c; int a, b; while (m--) { for(c = getchar(); c != 'A' && c != 'L'; c = getchar()); if (c == 'A') { scanf("%d\n", &a); if (whole[1] < a) ++ans; else add(a, 1, n, 1); } else { scanf("%d%d\n", &a, &b); clr(a, b, 1, n, 1); } } printf("%d\n",ans); return 0; }
4个标记维护区间内奶牛个数,左端最长连续空位,右端最长连续空位,区间内最长连续空位,然后就没了。
相关文章推荐
- 虚拟机ubunt14.04调整分辨率
- 在tomcat中部署测试Servlet(不用eclipse或MyEclipse的tomcat插件)
- Linux 远程复制
- Java的四种引用类型分析
- iframe用target指定跳转时,即使加了target="_self",还是会打开一个新的页面
- 搞清tomcat中的编解码
- leetcode--Counting Bits
- Xcode调用旧版本库出现Undefined symbols for architecture x86_64: ld: symbol(s) not found for architecture x86_64
- Myeclipse 错误:JVM terminated. Exit code=1
- Fragment间通信传递数据 Communicating with Other Fragments
- 我的第一次出国行
- TCP与UDP
- js内置对象
- 网络七层协议的形象说明
- Linux下php安装memcache扩展
- iOS自带的Social.framework 自带的社交分享SDK
- java多线程-join方法详解(附面试题)
- angular中 ng-if 指令中的ng-model等指令失效问题
- linux的启动流程
- utl_url.escape和utl_url.unescape