[Luogu P4215] 踩气球 (线段树)
题面
传送门:https://www.luogu.org/problemnew/show/P4215
Solution
这题十分有意思。
首先,我们可以先想想离线做法,因为在线做法可以从离线做法推出。(虽然这题推不出)
我们可以明确一点,一个熊孩子开心的时间是满足二分的要求的(如果他某个时刻开心了,那之后的时刻都会保持开心)。
对于判断一个区间是否为全0,我们可以用主席树以一个log的代价来判断。
得到每个熊孩子开心的时刻之后,我们就可以直接前缀和解决问题了。
时间复杂度O(m*log^2)
很可惜,这题强制在线。
很可惜*2,刚刚的做法跟正解一点关系都没有。
我们可以考虑用线段树。
问题是怎么判断一个熊孩子在某个操作后是否开心呢?
我们显然可以快速地判断线段树上的一个直接的区间(即这个区间可以用一个节点表示)是否全为0,问题是我们不能很快地判断一个非直接的区间是否全为0。
所以说,我们可以考虑把熊孩子“拆开”。
因为一个熊孩子的区间一定可以表示为线段树上的几个直接区间,我们可以在这些直接区间上打上标记,记录这个区间被哪几个熊孩子直接包含。
我们再记录一下每个熊孩子被拆成了几个区间。
一个区间全部变为0的时候,我们把它对应的熊孩子的记录值-1,当一个熊孩子记录值为0的时候,就代表着这个熊孩子的区间被彻底干掉了。
时间复杂度O(mlogn+qlogn)
就酱,这题就被我们切掉啦φ(>ω<*)
Code
//Luogu P4215 踩气球
//Oct,14th,2018
//有意思的线段树
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
long long read()
{
long long x=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int N=100000+100;
int ans,tot[N];
struct SegmentTree
{
#define lson (now<<1)
#define rson (now<<1|1)
#define mid ((now_l+now_r)/2)
vector <int> son[N<<2];
int IsClear[N<<2],cnt[N];
inline void update(int now)
{
IsClear[now]=IsClear[lson]&IsClear[rson];
}
void Mark(int L,int R,int x,int now,int now_l,int now_r)
{
if(now_l>=L and now_r<=R)
{
tot[x]++;
son[now].push_back(x);
return;
}
if(L<=mid) Mark(L,R,x,lson,now_l,mid);
if(R>mid) Mark(L,R,x,rson,mid+1,now_r);
}
void Sub(int x,int now,int now_l,int now_r)
{
if(now_l==now_r)
{
cnt[x]--;
if(cnt[x]==0)
IsClear[now]=true;
}
if(now_l!=now_r)
{
if(x<=mid) Sub(x,lson,now_l,mid);
else Sub(x,rson,mid+1,now_r);
update(now);
}
if(IsClear[now]==true)
for(int i=0;i<int(son[now].size());i++)
{
tot[son[now][i]]--;
if(tot[son[now][i]]==0)
ans++;
}
}
#undef lson
#undef rson
#undef mid
}sgt;
int n,m,q;
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
sgt.cnt[i]=read();
for(int i=1;i<=m;i++)
{
int L=read(),R=read();
sgt.Mark(L,R,i,1,1,n);
} int q=read(),lans=0;
for(int i=1;i<=q;i++)
{
int x=read();
x=(x+lans-1)%n+1;
sgt.Sub(x,1,1,n);
lans=ans;
printf("%d\n",lans);
}
return 0;
}
[Luogu P4215] 踩气球 (线段树)的更多相关文章
- 【BZOJ-4631】踩气球 线段树 + STL
4631: 踩气球 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 224 Solved: 114[Submit][Status][Discuss] ...
- bzoj 4631: 踩气球 线段树合并
4631: 踩气球 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 265 Solved: 136[Submit][Status][Discuss] ...
- bzoj 4631: 踩气球 线段树
题目: Description 六一儿童节到了, SHUXK 被迫陪着M个熊孩子玩一个无聊的游戏:有N个盒子从左到右排成一排,第i个盒子里装着Ai个气球. SHUXK 要进行Q次操作,每次从某一个盒子 ...
- 【bzoj4631】踩气球 线段树
题解: 真是很zz 我都想到线段树分治的思路了... 不过还是一道好题 首先跟线段树分治一样将区间投射到线段树上去 每次修改如果该个区间修改为0,则对他们对应的特定区间-1 这样每个区间会有一次变0, ...
- NOIP 2016 天天爱跑步 (luogu 1600 & uoj 261) - 线段树
题目传送门 传送点I 传送点II 题目大意 (此题目不需要大意,我认为它已经很简洁了) 显然线段树合并(我也不知道哪来这么多显然) 考虑将每条路径拆成两条路径 s -> lca 和 t -> ...
- hdu 1556 涂气球 线段树(区间更新~对区间[x,y]更新,求任意节点被更新的次数)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- luogu P4198 楼房重建——线段树
题目大意: 小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度.如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线 ...
- Luogu 3369 我用线段树骗了一道平衡树题……
这篇博客毫无意义-- 只是表达一下我仍然会写树状数组和线段树-- 题目链接 #include <cstdio> #include <cstring> #include < ...
- [Luogu P4198]楼房重建(线段树)
题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个 ...
随机推荐
- 【CF1425B】 Blue and Red of Our Faculty! 题解
原题链接 简要翻译: 有一个连通图,A和B同时从点1出发,沿不同的路径前进.原本,图上的每一条边都是灰色的.A将经过的边涂成红色,B将经过的边涂成蓝色的.每个回合每个人只能走灰色的边.当某个回合中不存 ...
- P1000 超级玛丽游戏
P1000 超级玛丽游戏 https://www.luogu.com.cn/problem/P1000 这就很简单了代码: #include <iostream> #include < ...
- python图像的绘制
转载:https://blog.csdn.net/haoji007/article/details/52063168 实际上前面我们就已经用到了图像的绘制,如: io.imshow(img) 这一行代 ...
- RHSA-2018:3032-低危: binutils 安全和BUG修复更新
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...
- RHSA-2019:0201-低危: systemd 安全更新
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...
- Python+Appium自动化测试(7)-截图方法
一,selenium模块的两种截图方法 get_screenshot_as_file(filename) 参数filename为截图文件保存的绝对路径,如: driver.get_screenshot ...
- 机器学习 KNN算法原理
K近邻(K-nearst neighbors,KNN)是一种基本的机器学习算法,所谓k近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表.比如:判断一个人的人品,只需要观察 ...
- day28 Pyhton MRO和C3算法
1.python多继承.一个类可以拥有多个父类 class ShenXian: # 神仙 def fei(self): print("神仙都会飞") class Monkey: # ...
- ORM查询相关的操作
必知必会13条 import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.setti ...
- MATLAB利用solve函数解多元一次方程组
matlab求解多元方程组示例: syms k1 k2 k3; [k1 k2 k3] = solve(-3-k3==6, 2-k1-k2+2*k3==11, 2*k1+k2-k3+1==6)或者用[k ...