【BZOJ4631】踩气球 题解(线段树)
----------------------
题目大意:给定一个长度为$n$的序列${a_i}$。现在有$m$个区间$[l_i,r_i]$和$q$个操作,每次选取一个$x$使得$a_x--$。问每一次操作后区间和为$0$的区间个数。
可以用主席树解决,但蒟蒻不会,蒟蒻只会写线段树QAQ。
对于每一个区间$[l_i,r_i]$,我们可以把它分解成线段树上$s$个区间,线段树每个结点维护一个向量数组,用来存包含它的区间。当某一个$a_x--$后,看线段树上区间和是否为0,如果是那么包含这个区间的区间$s--$。如果$s=0$那么$ans++$。
注意$update$向上回溯时也要判断一下是否为0,进行更新。
时间复杂度$O((m+q)\log n+n)$。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,q,m,a[],ans;
struct node
{
vector<int> v;
int l,r,val;
}tree[];
struct Node
{
int l,r,s;
}t[];
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void build(int index,int l,int r)
{
tree[index].l=l;
tree[index].r=r;
if (l==r)
{
tree[index].val=a[l];
return;
}
int mid=(l+r)>>;
build(index*,l,mid);
build(index*+,mid+,r);
tree[index].val=tree[index*].val+tree[index*+].val;
}
inline void update(int index,int pos,int v)
{
if (tree[index].l==tree[index].r)
{
tree[index].val+=v;
if (tree[index].val==)
{
for (int i=;i<tree[index].v.size();i++)
{
t[tree[index].v[i]].s--;
if (t[tree[index].v[i]].s==) ans++;
}
}
return;
}
int mid=(tree[index].l+tree[index].r)>>;
if (pos<=mid) update(index*,pos,v);
else update(index*+,pos,v);
tree[index].val=tree[index*].val+tree[index*+].val;
if (tree[index].val==)
{
for (int i=;i<tree[index].v.size();i++)
{
t[tree[index].v[i]].s--;
if (t[tree[index].v[i]].s==) ans++;
}
}
}
inline void split(int index,int l,int r,int id)
{
if (l<=tree[index].l&&tree[index].r<=r)
{
tree[index].v.push_back(id);
t[id].s++;
return;
}
int mid=(tree[index].l+tree[index].r)>>;
if (l<=mid) split(index*,l,r,id);
if (r>mid) split(index*+,l,r,id);
}
int main()
{
n=read(),m=read();
for (int i=;i<=n;i++) a[i]=read();
build(,,n);
for (int i=;i<=m;i++) t[i].l=read(),t[i].r=read();
for (int i=;i<=m;i++) split(,t[i].l,t[i].r,i);
q=read();
while(q--)
{
int x=read();
x=(x+ans-)%n+;
update(,x,-);
printf("%d\n",ans);
}
return ;
}
【BZOJ4631】踩气球 题解(线段树)的更多相关文章
- 【BZOJ4631】踩气球 链表+线段树+堆
[BZOJ4631]踩气球 Description 六一儿童节到了, SHUXK 被迫陪着M个熊孩子玩一个无聊的游戏:有N个盒子从左到右排成一排,第i个盒子里装着Ai个气球. SHUXK 要进行Q次操 ...
- 【BZOJ 4631】4631: 踩气球 (线段树)
4631: 踩气球 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 316 Solved: 153 Description 六一儿童节到了, SHUX ...
- bzoj4631踩气球
bzoj4631踩气球 题意: 有一个序列和一个区间集合,每次将序列中的一个数-1,求此时集合里有多少个区间和为0.序列大小≤100000,区间数≤100000,操作数≤100000. 题解: 此题解 ...
- POJ2182题解——线段树
POJ2182题解——线段树 2019-12-20 by juruoOIer 1.线段树简介(来源:百度百科) 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线 ...
- luoguP5105 不强制在线的动态快速排序 [官方?]题解 线段树 / set
不强制在线的动态快速排序 题解 算法一 按照题意模拟 维护一个数组,每次直接往数组后面依次添加\([l, r]\) 每次查询时,暴力地\(sort\)查询即可 复杂度\(O(10^9 * q)\),期 ...
- 理想乡题解 (线段树优化dp)
题面 思路概述 首先,不难想到本题可以用动态规划来解,这里就省略是如何想到动态规划的了. 转移方程 f[i]=min(f[j]+1)(max(i-m,0)<=j<i 且j符合士兵限定) 注 ...
- BZOJ4631 : 踩气球
将所有盒子插入链表,每当一个盒子变空时,从链表里删去它. 查一下它的前驱后继$pre,nxt$,那么$[pre+1,nxt-1]$都是空的. 每次对于$[A,B]$这段都为空,对小朋友按$R$维护线段 ...
- POJ 3468 A Simple Problem with Integers(详细题解) 线段树
这是个线段树题目,做之前必须要有些线段树基础才行不然你是很难理解的. 此题的难点就是在于你加的数要怎么加,加入你一直加到叶子节点的话,复杂度势必会很高的 具体思路 在增加时,如果要加的区间正好覆盖一个 ...
- [bzoj2752]高速公路 题解(线段树)
2752: [HAOI2012]高速公路(road) Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2102 Solved: 887[Submit] ...
随机推荐
- day31 反射,内置方法,元类
目录 一.反射 1 什么是反射 2 如何实现反射 二.内置方法 1 什么是内置方法 2 为什么要用内置方法 3 如何使用内置方法 3.1 str 3.2 del 三.元类 1 什么是元类 2 clas ...
- shell专题(三):Shell脚本入门
1.脚本格式 脚本以#!/bin/bash开头(指定解析器) 2.第一个Shell脚本:helloworld (1)需求:创建一个Shell脚本,输出helloworld (2)案例实操: [atgu ...
- python eval函数,将列表样式的字符串转化为列表
python eval函数,将列表样式的字符串转化为列表 >>> str_1 = '[1,2,3,4,5,6]'>>> type(str_1)<type 's ...
- 爬虫前篇 /https协议原理剖析
爬虫前篇 /https协议原理剖析 目录 爬虫前篇 /https协议原理剖析 1. http协议是不安全的 2. 使用对称秘钥进行数据加密 3. 动态对称秘钥和非对称秘钥 4. CA证书的应用 5. ...
- bzoj3375[Usaco2004 Mar]Paranoid Cows 发疯的奶牛*
bzoj3375[Usaco2004 Mar]Paranoid Cows 发疯的奶牛 题意: 依次给出n只奶牛的产奶时间段,求最大的k使得前k只奶牛不存在一个时间段被另一个时间段完全覆盖的情况.n≤1 ...
- Go Pentester - HTTP CLIENTS(2)
Building an HTTP Client That Interacts with Shodan Shadon(URL:https://www.shodan.io/) is the world' ...
- ffmpeg拉流长时间堵塞解决方式
由于网络堵塞或者推流端错误导致拉流端没有流数据,ffmpeg主要会堵塞两个函数,直到下次流数据的到来 avformat_open_input() 该函数是在打开流数据时,如果没有这个流的ip,http ...
- dbca 建库报错 ORA-00600 解决办法
[oracle@tim1 ~]$ dbca## An unexpected error has been detected by HotSpot Virtual Machine:## SIGSEGV ...
- PyQt5绘图
QPainter 功能:QPainter实现在QWidget上画图功能 说明:绘图必须在paintEvent中完成,且要在bengin和end之间作图 接口: 方法 描述 begin 开始画图 end ...
- python多进程之multiprocessing
什么是多进程? 简单的理解:单板上运行的一个程序就是一个进程.进程是操作系统分配资源的最小单位,不同的进程之间资源不共享,进程间通信需要使用特定的方式.python提供了自带的multiprocess ...