Solution

这题的解法非常巧妙啊~
我们发现只有一个箱子中的气球全部被踩完后, 才可能对答案产生贡献, 因此用数组维护每个箱子中剩余的气球个数.
考虑每次可能对处于哪些区间的熊孩子产生影响: 我们设当前箱子为\(p\), 通过链表查找到最小的\(l\)满足\([l, p]\)区间的所有箱子都不含有气球, 以及最大的\(r\)满足\([p, r]\)区间中的所有箱子都不含有气球. 则会变高兴的熊孩子满足其对应区间的左端点在\([l, p]\)中且右端点在\([p, r]\)中. 我们用一颗可持久化线段树来维护每个位置\(p\)有哪些熊孩子满足\(l \le p\), 且将其对应的\(r\)存入线段树中. 每次操作后, 在线段树中容斥即可.

#include <cstdio>
#include <cctype>
#include <algorithm>namespace Zeonfai
{inline int getInt(){int a = 0, sgn = 1;char c;while(! isdigit(c = getchar())) if(c == '-') sgn *= -1;while(isdigit(c)) a = a * 10 + c - '0', c = getchar();return a * sgn;}
}
const int N = (int)1e5, M = (int)1e5;
int n, m;
struct bearChild
{int L, R;inline int friend operator <(bearChild a, bearChild b){return a.L == b.L ? a.R < b.R : a.L < b.L;}
}chd[M];
struct segmentTrees
{struct node{node *suc[2];int cnt;inline node() {cnt = 0; suc[0] = suc[1] = NULL;}};node *rt[N + 1];node* build(int L, int R){node *u = new node;if(L == R) return u;u->suc[0] = build(L, L + R >> 1); u->suc[1] = build((L + R >> 1) + 1, R);return u;}inline void build() {rt[0] = build(1, n);}inline void newTree(int id) {rt[id] = rt[id - 1];}inline node* insert(node *_u, node *u, int L, int R, int pos){if(u == _u) u = new node, *u = *_u;++ u->cnt;if(L == R) return u;if(pos <= L + R >> 1) u->suc[0] = insert(_u->suc[0], u->suc[0], L, L + R >> 1, pos);else u->suc[1] = insert(_u->suc[1], u->suc[1], (L + R >> 1) + 1, R, pos);return u; }inline void insert(int id, int pos){rt[id] = insert(rt[id - 1], rt[id], 1, n, pos);}int query(node *u, int curL, int curR, int L, int R){if(curL >= L && curR <= R) return u->cnt;int mid = curL + curR >> 1;int res = 0;if(L <= mid) res += query(u->suc[0], curL, mid, L, R);if(R > mid) res += query(u->suc[1], mid + 1, curR, L, R);return res;}inline int query(int id, int L, int R){return query(rt[id], 1, n, L, R);}
}seg;
int main()
{#ifndef ONLINE_JUDGEfreopen("balloon.in", "r", stdin);freopen("balloon.out", "w", stdout);#endifusing namespace Zeonfai;n = getInt(), m = getInt();static int a[N + 1];for(int i = 1; i <= n; ++ i) a[i] = getInt();for(int i = 0; i < m; ++ i) chd[i].L = getInt(), chd[i].R = getInt();std::sort(chd, chd + m);seg.build();for(int i = 1, p = 0; i <= n; ++ i){seg.newTree(i);for(; p < m && chd[p].L == i; ++ p) seg.insert(i, chd[p].R);}static int pre[N + 1], nxt[N + 1];for(int i = 1; i <= n; ++ i) pre[i] = i - 1, nxt[i] = i + 1;pre[1] = nxt[n] = -1;int q = getInt(), ans = 0;for(int i = 0; i < q; ++ i){int pos = (getInt() + ans - 1) % n + 1; -- a[pos];if(! a[pos]){ans += seg.query(pos, pos, ~ nxt[pos] ? nxt[pos] - 1 : n);if(~ pre[pos]) ans -= seg.query(pre[pos], pos, ~ nxt[pos] ? nxt[pos] - 1 : n);if(~ nxt[pos]) pre[nxt[pos]] = pre[pos];if(~ pre[pos]) nxt[pre[pos]] = nxt[pos];}printf("%d\n", ans);}
}

转载于:https://www.cnblogs.com/ZeonfaiHo/p/7348178.html

BZOJ 4631 踩气球相关推荐

  1. bzoj 4631: 踩气球(线段树)

    4631: 踩气球 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 375  Solved: 189 [Submit][Status][Discuss ...

  2. 【BZOJ-4631】踩气球 线段树 + STL

    4631: 踩气球 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 224  Solved: 114 [Submit][Status][Discuss ...

  3. 【bzoj4631】踩气球

    4631: 踩气球 Time Limit: 10 Sec   Memory Limit: 256 MB Submit: 372   Solved: 186 [ Submit][ Status][ Di ...

  4. bzoj4631踩气球

    bzoj4631踩气球 题意: 有一个序列和一个区间集合,每次将序列中的一个数-1,求此时集合里有多少个区间和为0.序列大小≤100000,区间数≤100000,操作数≤100000. 题解: 此题解 ...

  5. 记萌新赛的命题过程与踩气球过程

    从命题环节开始记起吧,踩气球部分放在后半段压轴. 大约$20$天以前,那天早上我刚下火车,得知今年比赛命题组组长是$xiang578$,老师发的命题人员名单中并没有我.出于对命题工作的好奇与热爱,我向 ...

  6. noj 1142 F 踩气球

    Problem F 踩气球 时限:1000ms 内存限制:10000K 总时限:3000ms 描述: 六一儿童节,小朋友们做踩气球游戏,气球的编号是1-100,两位小朋友各踩了一些气球,要求他们报出自 ...

  7. 【算法实验二】--【回溯法】--踩气球

    1142.踩气球 时限:1000ms 内存限制:10000K  总时限:3000ms 描述 六一儿童节,小朋友们做踩气球游戏,气球的编号是1-100,两位小朋友各踩了一些气球,要求他们报出自己所踩气球 ...

  8. 踩气球ZOJ1003

    描述: 六一儿童节,小朋友们做踩气球游戏,气球的编号是1-100,两位小朋友各踩了一些气球,要求他们报出自己所踩气球的编号的乘积.现在需要你编一个程序来判断他们的胜负,判断的规则是这样的:如果两人都说 ...

  9. BZOJ4631: 踩气球

    BZOJ4631: 踩气球 线段树 的 奇幻世界 题解: 在dalao fqk的模拟赛里我自己想出来的! 撒花 撒花 线段树维护气球,把一个孩子拆成若干个线段树上的区间,并放在对应线段树节点的vect ...

  10. 【NOJ1142】【算法实验二】踩气球

    1142.踩气球 时限:1000ms 内存限制:10000K 总时限:3000ms 描述 六一儿童节,小朋友们做踩气球游戏,气球的编号是1-100,两位小朋友各踩了一些气球,要求他们报出自己所踩气球的 ...

最新文章

  1. docker $PWD路径_深入浅出Docker 镜像
  2. urlencode urldecode
  3. 【机器学习】谷歌的速成课程(二)
  4. DevExpress的下拉框控件ComboxBoxEdit怎样绑定键值对选项
  5. html下拉列表插件,js+CSS实现模拟华丽的select控件下拉菜单效果
  6. Redis源码分析(一)redis.c //redis-server.c
  7. shell 12 21 filename重定向的含义和区别
  8. A股开盘:深证区块链50指数跌0.02%,丽鹏股份、爱施德涨停
  9. C++是一款设计非常失败的语言吗?
  10. placeholder在某些浏览器下不垂直居中问题
  11. SpringBoot移除内置Tomcat
  12. JDK参考文档的使用
  13. Unity 相机的移动旋转以及拉近拉远的原理
  14. 你想要的宏基因组-微生物组知识全在这(2020.5)
  15. HTTP请求和请求头的详解
  16. 高等数学上核心概念:谈谈导数,微分,积分之间的关系(导数篇)
  17. risc-v 栈分析
  18. 压缩算法——谷歌Webp
  19. SitePoint播客#47:将死苹果
  20. 计算机网络:网络层的功能概述

热门文章

  1. uni-app的笔记
  2. 链家二手房100页Xpath爬取保存csv
  3. VMware 下载与安装 链接分享 巨好用
  4. OA系统的“四化”演变过程
  5. react+typescript通过window.xxx挂载属性报错的解决方案
  6. Android开发怎么获取美工素材
  7. es6学习(二) 函数进阶 this指向问题、深拷贝、浅拷贝
  8. 深度学习数据自动编码器_我对从开放大学学习编码以进行数据分析的评论
  9. STM32F103C8 GPIO
  10. python爬取某人所有微博_用python写网络爬虫爬取新浪微博评论