4631: 踩气球

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 265  Solved: 136
[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]中的气球已经全部被踩爆)。
 
  这题好像怎么做都行,于是我写了一发线段树合并。
  维护n棵权值线段树,把每个区间以左端点为值插入右端点代表的线段树中。
  再用个并查集维护每个点前第一个没被踩完的盒子$f[i]$。
  每次踩空一个盒子i,找到$f[i]$,把$i$这棵线段树中大于$f[i]$的点删掉,再把$i$合并到$f[i]$上。
  

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100005
using namespace std;
int n,m;
int c[N],now;
struct node
{
int l,r,sum;
}a[N*];int cnt;
void add(int x,int l,int r,int z)
{
if(l==r)
{
a[x].sum++;
return ;
}
int mid=(l+r)>>;
if(z<=mid)
{
if(!a[x].l)a[x].l=++cnt;
add(a[x].l,l,mid,z);
}
else
{
if(!a[x].r)a[x].r=++cnt;
add(a[x].r,mid+,r,z);
}
a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
return ;
}
int f[N];
int find(int x)
{
if(f[x]==x)return x;
return f[x]=find(f[x]);
}
int la=;
int root[N];
void del(int x,int l,int r,int z)
{
if(l==r)
{
la+=a[x].sum;
a[x].sum=;
return ;
}
int mid=(l+r)>>;
if(z<=mid)
{
if(a[a[x].l].sum)del(a[x].l,l,mid,z);
}
if(a[a[x].r].sum)del(a[x].r,mid+,r,z);
a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
return ;
}
void merge(int x,int y,int l,int r)
{
if(l==r)
{
a[x].sum+=a[y].sum;
return ;
}
int mid=(l+r)>>;
if(a[x].l)
{
if(a[y].l)merge(a[x].l,a[y].l,l,mid);
}
else a[x].l=a[y].l;
if(a[x].r)
{
if(a[y].r)merge(a[x].r,a[y].r,mid+,r);
}
else a[x].r=a[y].r;
a[x].sum=a[a[x].r].sum+a[a[x].l].sum;
return ;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&c[i]);
for(int i=;i<=n;i++)root[i]=++cnt;
for(int i=;i<=n;i++)f[i]=i;
int t1,t2;
for(int i=;i<=m;i++)
{
scanf("%d%d",&t1,&t2);
add(root[t2],,n,t1);
}
int q;scanf("%d",&q); for(int i=;i<=q;i++)
{
scanf("%d",&t1);
t1=(t1-+la)%n+;
c[t1]--;
if(c[t1]==)
{
f[t1]=t1-;
int aa=find(t1);
del(root[t1],,n,aa+);
merge(root[aa],root[t1],,n);
}
printf("%d\n",la);
}
return ;
}

bzoj 4631: 踩气球 线段树合并的更多相关文章

  1. bzoj 4631: 踩气球 线段树

    题目: Description 六一儿童节到了, SHUXK 被迫陪着M个熊孩子玩一个无聊的游戏:有N个盒子从左到右排成一排,第i个盒子里装着Ai个气球. SHUXK 要进行Q次操作,每次从某一个盒子 ...

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

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

  3. BZOJ.3545.[ONTAK2010]Peaks(线段树合并)

    题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. \(Solut ...

  4. BZOJ:5457: 城市(线段树合并)(尚待优化)

    5457: 城市 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 18  Solved: 12[Submit][Status][Discuss] Des ...

  5. [Luogu P4215] 踩气球 (线段树)

    题面 传送门:https://www.luogu.org/problemnew/show/P4215 Solution 这题十分有意思. 首先,我们可以先想想离线做法,因为在线做法可以从离线做法推出. ...

  6. bzoj 4756 Promotion Counting —— 线段树合并

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4756 合并子树的权值线段树: merge 返回 int 或者是 void 都可以. 代码如下 ...

  7. 【bzoj4631】踩气球 线段树

    题解: 真是很zz 我都想到线段树分治的思路了... 不过还是一道好题 首先跟线段树分治一样将区间投射到线段树上去 每次修改如果该个区间修改为0,则对他们对应的特定区间-1 这样每个区间会有一次变0, ...

  8. BZOJ 4631 踩气球

    BZOJ上内存小了会WA.... 线段树上挂链表. #include<iostream> #include<cstdio> #include<cstring> #i ...

  9. 【BZOJ 4631】4631: 踩气球 (线段树)

    4631: 踩气球 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 316  Solved: 153 Description 六一儿童节到了, SHUX ...

随机推荐

  1. centos7 sentry部署指南

    依赖说明 sentry官方推荐docker方式安装,使用到了docker-compose.docker至少是1.10.3以上的版本.为此需要使用centos7. 安装docker #添加yum 源 # ...

  2. 大数据入门第十四天——Hbase详解(二)基本概念与命令、javaAPI

    一.hbase数据模型 完整的官方文档的翻译,参考:https://www.cnblogs.com/simple-focus/p/6198329.html 1.rowkey 与nosql数据库们一样, ...

  3. C# online update demo

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  4. 20155204《网络对抗》Exp 6 信息搜集与漏洞扫描

    20155204<网络对抗>Exp 6 信息搜集与漏洞扫描 一.实验后回答问题 1.哪些组织负责DNS,IP的管理. 互联网名称与数字地址分配机构,简称ICANN机构,决定了域名和IP地址 ...

  5. 20155229《网络对抗技术》Exp8:Web基础

    实验内容 (1).Web前端HTML 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. (2).Web前端javascipt 理解JavaS ...

  6. 20155339 Exp7 网络欺诈防范

    20155339 Exp7 网络欺诈防范 .基础问题回答 (1)通常在什么场景下容易受到DNS spoof攻击 当连接局域网的时候应该最容易被攻击,比如说连接了一些不清楚是什么的WiFi其实是很容易收 ...

  7. 【WPF】两则动画效果

    原文:[WPF]两则动画效果 引言 利用WPF的动画可以轻而易举的实现各种各样的特效,如擦除,滑动进入等,先看两个效果图 第一个效果 这个动画其实利用了OpacityMask和LinearGradie ...

  8. 浅析arm的异常、中断和arm工作模式的联系

    说到异常向量,会让人联想到中断向量.其实,中断是属于异常的子集的,也就是说中断其实是异常其中的一种. 回到异常向量,他其实是一张表格,每个格子里存放的是一个地址,或者是一个跳转命令,不管是哪个,其目的 ...

  9. 【LG4248】[AHOI2013]差异

    [LG4248][AHOI2013]差异 题面 洛谷 题解 后缀数组版做法戳我 我们将原串\(reverse\),根据后缀自动机的性质,两个后缀的\(lcp\)一定是我们在反串后两个前缀的\(lca\ ...

  10. Bluedroid协议栈BTU线程处理HCI数据流程分析

    在蓝牙enable的过程中会进行多个线程的创建以及将线程与队列进行绑定的工作.该篇文章主要分析一下处理hci数据这个 线程. void BTU_StartUp(void) { ... btu_bta_ ...