4631: 踩气球

Time Limit: 10 Sec   Memory Limit: 256 MB
Submit: 372   Solved: 186
[ Submit][ Status][ Discuss]

Description

六一儿童节到了, SHUXK 被迫陪着M个熊孩子玩一个无聊的游戏:有N个盒子从左到右排成一排,第i个盒子里装着Ai个气球。
SHUXK 要进行Q次操作,每次从某一个盒子里拿出一个没被踩爆的气球,然后熊孩子们就会立刻把它踩爆。
这M个熊孩子每个人都指定了一个盒子区间[Li, Ri]。 如果某一个时刻,一个熊孩子发现自己选定的盒子区间[Li, Ri]中的所
有气球都已经被踩爆了,他就会非常高兴(显然之后他一直会很高兴)。
为了不辜负将自己的任务强行塞给 SHUXK 的那个人的期望, SHUXK 想向你询问: 
他每次操作过后会有多少个熊孩子很高兴。

Input

第一行包含两个正整数N和M,分别表示盒子和熊孩子的个数。
第二行包含N个正整数Ai( 1 < = Ai < = 10^5),表示每个盒子里气球的数量。
以下M行每行包含两个正整数Li, Ri( 1 < = Li < = Ri < = N),分别表示每一个熊孩子指定的区间。
以下一行包含一个正整数Q,表示 SHUXK 操作的次数。
以下Q行每行包含一个正整数X,表示这次操作是从第X个盒子里拿气球。为
了体现在线,我们对输入的X进行了加密。
假设输入的正整数是x',那么真正的X = (x' + Lastans − 1)Mod N + 1。其
中Lastans为上一次询问的答案。对于第一个询问, Lastans = 0。
输入数据保证1 < = x' < = 10^9, 且第X个盒子中有尚未被踩爆的气球。
N < = 10^5 ,M < = 10^5 �,Q < = 10^5

Output

包含Q行,每行输出一个整数,表示 SHUXK 一次操作后询问的
答案。答案的顺序应与输入数据的顺序保持一致。

Sample Input

5 3
1 1 1 1 1
5 5
2 2
1 3
5
4
2
5
2
3

Sample Output

0
1
1
2
3
【样例说明】
实际上每次操作的盒子是: 4 2 1 3 5
在第二次操作后,第二个熊孩子会高兴 (区间[2,2]中的气球已经全部被踩爆)。
在第四次操作后,第三个熊孩子会高兴(区间[1,3]中的气球已经全部被踩爆)。
在第五次操作后,第一个熊孩子会高兴(区间[5,5]中的气球已经全部被踩爆)。

HINT

Source

[ Submit][ Status][ Discuss]



这题有多种搞法。。

先说一下我的方法

考虑只有当一个盒子内的气球被全部踩完以后才对答案有贡献

那么可以考虑一下当一个盒子内气球被踩完后的变化

对于盒子X被踩完,那么也就相当于是把X左边踩完的区间和X右边踩完的区间合并起来,然后将处于这个区间内的熊孩子删除并计入答案

那么我们可以考虑启发式合并。。直接暴力把小的区间合并进大的区间即可,合并的时候顺带统计一下答案。。

然后这题就做完了。。

后来百度了一下其他人的题解,又有新的启发

还有另一种做法,就是利用线段树,把熊孩子们按R排序后依次加入到树中,维护L的最大值

然后每次踩气球也同样是上面的思路合并两个区间,然后对于合并出来的新区间[A,B],在主席树上查询[1,B]区间内L的最大值,如果大于等于A就取出来删掉计入答案即可

代码(启发式合并):

#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;typedef long long LL;const int INF = 2147483647;
const int maxn = 100100;struct data{int to,id;
};int n,m,q,a[maxn],lastans;
int fa[maxn],L[maxn],R[maxn],siz[maxn];
bool del[maxn];
vector<data> link[maxn];inline LL getint()
{LL ret = 0,f = 1;char c = getchar();while (c < '0' || c > '9'){if (c == '-') f = -1;c = getchar();}while (c >= '0' && c <= '9')ret = ret * 10 + c - '0',c = getchar();return ret * f;
}int main()
{n = getint(); m = getint();for (int i = 1; i <= n; i++) a[i] = getint();for (int i = 1; i <= m; i++){int u = getint(),v = getint();link[u].push_back((data){v,i});link[v].push_back((data){u,i});}for (int i = 1; i <= n; i++){L[i] = R[i] = i;siz[fa[i] = i] = 1;}a[0] = a[n + 1] = 130;q = getint();for (int i = 1; i <= q; i++){int x = (getint() + lastans - 1) % n + 1;if (--a[x]) {printf("%d\n",lastans); continue;}{int l,r,ac;if (a[x - 1] && a[x + 1]) l = r = ac = x;else if (a[x - 1]) l = r = x , ac = fa[x + 1];else if (a[x + 1]) l = r = x , ac = fa[x - 1];else if (siz[fa[x - 1]] < siz[fa[x + 1]]) l = L[fa[x - 1]] , r = x , ac = fa[x + 1];else l = x , r = R[fa[x + 1]] , ac = fa[x - 1];for (int k = l; k <= r; k++){siz[fa[k]] = 0;if (ac != fa[k])  fa[k] = L[fa[k]] = R[fa[k]] = 0;fa[k] = ac; siz[ac]++;L[ac] = min(L[ac],k); R[ac] = max(R[ac],k);for (int j = 0; j < link[k].size(); j++){if (del[link[k][j].id]) {link[k].erase(link[k].begin() + j--); continue;}if (fa[link[k][j].to] != fa[k]) continue;lastans++;del[link[k][j].id] = 1;link[k].erase(link[k].begin() + j--);}}printf("%d\n",lastans);}}return 0;
}

【bzoj4631】踩气球相关推荐

  1. bzoj4631踩气球

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

  2. BZOJ4631: 踩气球

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

  3. [bzoj4631]踩气球

    题目大意 有一个序列,每次将一个位置的数减去1(保证这个数大于0) 有m个区间,每次操作后你都要输出有多少个区间和为0. 强制在线. 线段树搞搞 这m个区间可以被分割到线段树上的log个区间,那我们就 ...

  4. BZOJ4631 踩气球

    每个熊孩子抽象成平面上的一个点,横坐标为左边界,纵坐标为右边界,点权为区间长度,把第x个盒子拿空相当于把以(1,x)为左下角,(x,n)为右上角的矩形内的点减一,答案就是有多少个点等于0,因为每个点最 ...

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

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

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

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

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

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

  8. noj 1142 F 踩气球

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

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

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

最新文章

  1. Webpack 最佳实践总结(一)
  2. LOOPS HDU - 3853 (概率dp):(希望通过该文章梳理自己的式子推导)
  3. Java阶段性测试--第二三大题参考代码
  4. Mysql在离线安装时提示:error: Found option without preceding group in config file
  5. mycat 启动失败 The specified size exceeds the maximum representable size JVM exited while loading the a
  6. 【虚拟主机篇】asp页面实现301重定向方法
  7. 图片不显示问题 图片url监测改变问题
  8. JQuery动画之淡入淡出动画
  9. RabbitMQ 拓展基础组件封装思路
  10. vue 父链和子组件索引_解决Vue2.x父组件与子组件之间的双向绑定问题
  11. Spring学习笔记3——使用注解的方式完成注入对象中的效果
  12. 游戏开发之C++多继承及虚继承(C++基础)
  13. qrect在图片上显示矩形框_Mac上用LabelImg手动标记图片
  14. c语言怎么下载步骤,C语言教程下载_C语言教程APP手机最新版安装 - 风云下载
  15. cfree安装与使用
  16. halo输入QQ号获取QQ头像和名称
  17. java 长字符串变短_如何将一个很长的String变短,再根据短的String还原?
  18. 四川省国际科技合作基地(国合基地)申报条件程序
  19. win7访问XP或者2003共享,提示密码错误的解决办法
  20. wifi 频段表_史上最全无线通信频率分配表,转走收藏!

热门文章

  1. Android dimen集合(建议收藏)
  2. cocos保存图片到手机相册
  3. C 语言实现的滑动平均滤波算法,滑动平均滤波算法(递推平均滤波法)
  4. 《SpringCloud》笔记二:项目导入
  5. [vue] nodejs安装教程
  6. sed删除匹配到的第一行记录
  7. 三种基于CUDA的归约计算
  8. ffmpeg教程 如何读取音频或视频的媒体信息?
  9. xstart 工具使用
  10. java图像灰度直方图_图像灰度变换、二值化、直方图