4631: 踩气球

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 260  Solved: 133
[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

按r排序,每次询问二分查找r的位置,线段树上查找最大值就可以了(我仍然想不出来)

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
#define N 200010
struct query
{
int l,r;
}q[N];
int n,m,Q,cnt,ans,lastans;
int pre[N],nxt[N],a[N];
PII tree[N<<];
bool cp(query x,query y)
{
if(x.r!=y.r) return x.r<y.r;
return x.l>y.l;
}
void update(int l,int r,int x,int pos,int num)
{
if(l==r)
{
tree[x].first=num;
tree[x].second=l;
return;
}
int mid=(l+r)>>;
if(pos<=mid) update(l,mid,x<<,pos,num);
else update(mid+,r,x<<|,pos,num);
if(tree[x<<].first>tree[x<<|].first) tree[x]=tree[x<<];
else tree[x]=tree[x<<|];
}
PII query(int l,int r,int x,int a,int b)
{
if(l>b||r<a) return make_pair(,);
if(l>=a&&r<=b) return tree[x];
int mid=(l+r)>>;
PII t1=query(l,mid,x<<,a,b),t2=query(mid+,r,x<<|,a,b);
if(t1.first>t2.first) return t1; else return t2;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)
{
scanf("%d",&a[i]);
pre[i]=i-; nxt[i]=i+;
}
for(int i=;i<=m;++i) scanf("%d%d",&q[i].l,&q[i].r);
sort(q+,q+m+,cp);
for(int i=;i<=m;++i) update(,m,,i,q[i].l);
scanf("%d",&Q);
while(Q--)
{
int x; scanf("%d",&x);
x=(x+lastans-)%n+;
a[x]--;
if(a[x])
{
printf("%d\n",ans);
continue;
}
int pos1=n,pos2=n,left=pre[x]+,right=nxt[x]-;
int l=,r=n+;
while(r-l>)
{
int mid=(l+r)>>;
if(q[mid].r>=left) r=pos1=mid; else l=mid;
}
l=; r=n+;
while(r-l>)
{
int mid=(l+r)>>;
if(q[mid].r<=right) l=pos2=mid; else r=mid;
}
/* if(q[pos1].r>right) pos1--;
if(q[pos2].r>right) pos2--;
if(pre[x]==0) pos1=1; */
// printf("x=%d\n",x);
// printf("left=%d right=%d\n",left,right);
// printf("pos1=%d pos2=%d\n",pos1,pos2);
while()
{
PII t=query(,m,,pos1,pos2);
// printf("query=%d\n",t.first);
if(t.first>=left&&t.first<=right&&t.first!=)
{
ans++;
update(,m,,t.second,);
} else break;
}
nxt[pre[x]]=nxt[x];
pre[nxt[x]]=pre[x];
lastans=ans;
printf("%d\n",ans);
}
return ;
}

bzoj4631的更多相关文章

  1. 【BZOJ4631】踩气球 链表+线段树+堆

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

  2. bzoj4631踩气球

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

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

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

  4. BZOJ4631 : 踩气球

    将所有盒子插入链表,每当一个盒子变空时,从链表里删去它. 查一下它的前驱后继$pre,nxt$,那么$[pre+1,nxt-1]$都是空的. 每次对于$[A,B]$这段都为空,对小朋友按$R$维护线段 ...

  5. 【bzoj4631】踩气球 线段树

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

  6. 【BZOJ4631】踩气球 题解(线段树)

    题目链接 ---------------------- 题目大意:给定一个长度为$n$的序列${a_i}$.现在有$m$个区间$[l_i,r_i]$和$q$个操作,每次选取一个$x$使得$a_x--$ ...

随机推荐

  1. eclipse pom.xml 报错org.apache.maven.plugin.war.WarMojo的解决办法

    如题,maven项目eclipse提示pom.ml有错,提示信息就是org.apache.maven.plugin.war.WarMojo. 然后执行 maven install 出现如下错误提示 [ ...

  2. Enchantress(hdu 3922)

    首先考虑覆盖三个点的情况,有两种情况: ①:三个点都在圆上,则该圆是三角形的外接圆 ②:两个点在圆上,第三个点在圆内,且在圆上的两个点之间的线段一定是直径 如果是多个圆,就不停地迭代. 有一点重要的是 ...

  3. ajax请求数据之后在已经有的数据前面打对勾的方法

    今天遇到这么一个需求: 选择一部分人,在点击确定的时候添加到对应的div中,也就是添加到对应的表单下面,当再次查询的时候需要在已经选过的人的复选框前面打伤对勾.

  4. TimePickerDialog

    package com.pingyijinren.helloworld.activity; import android.app.TimePickerDialog; import android.su ...

  5. Hibernate学习笔记(三)

    我是从b站视频上学习的hibernate框架,其中有很多和当前版本不符合之处,我在笔记中进行了修改以下是b站视频地址:https://www.bilibili.com/video/av14626440 ...

  6. neo4j在linux下的安装

    1. Neo4j简介 Neo4j是一个用Java实现的.高性能的.NoSQL图形数据库.Neo4j 使用图(graph)相关的概念来描述数据模型,通过图中的节点和节点的关系来建模.Neo4j完全兼容A ...

  7. Samba简单配置--匿名用户共享资料可读可写的实现

    http://e-mailwu.blog.163.com/blog/static/65104036200931893921923/ http://www.cnblogs.com/god_like_do ...

  8. 【Nginx】基本数据结构

    整型的封装 typedef intptr_t ngx_int _t;//有符号整型 typedef uintptr_t ngx_uint_t;//无符号整型 字符串的封装 typedef struct ...

  9. [RxJS] Implement RxJS `mergeMap` through inner Observables to Subscribe and Pass Values Through

    Understanding sources and subscribers makes it much easier to understand what's going on with mergeM ...

  10. poj 1258 Agri-Net(Prim)(基础)

    Agri-Net Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44487   Accepted: 18173 Descri ...