题目:

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 一次操作后询问的

答案的顺序应与输入数据的顺序保持一致。

题解:

这道题貌似有很多解法,那我就说说我的做法吧.

首先用一维数组把问题简化.

然后就是每次操作之后求有多少的区间变成了全部为0的区间

但是我们发现有很多区间都要进行询问,我们不可能遍历所有区间去查找

所以我们考虑每次修改单点会对哪些区间造成影响

一次修改会对线段树上的logn的区间造成影响,所以我们看有多少询问区间覆盖了这个区间

也就是吧询问区间拆成线段树的多个区间组合,发现最多也是logn的

所以用链表维护一个线段树区间上表示的询问区间即可。

感觉这个做法挺简单的,不用高级数据结构

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. typedef long long ll;
  6. inline void read(int &x){
  7. x=0;char ch;bool flag = false;
  8. while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
  9. while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
  10. }
  11. const int maxn = 100010;
  12. struct Node{
  13. int id,next;
  14. }G[maxn*20];
  15. int head[maxn<<2],cnt;
  16. inline void add(int u,int v){
  17. G[++cnt].id = v;
  18. G[cnt].next = head[u];
  19. head[u] = cnt;
  20. }
  21. int T[maxn<<2],num[maxn],a[maxn];
  22. inline void build(int rt,int l,int r){
  23. if(l == r){
  24. T[rt] = (bool)a[l];
  25. return ;
  26. }
  27. int mid = l+r >> 1;
  28. build(rt<<1,l,mid);
  29. build(rt<<1|1,mid+1,r);
  30. T[rt] = T[rt<<1] + T[rt<<1|1];
  31. }
  32. inline void insert(int rt,int l,int r,int L,int R,int nw){
  33. if(L <= l && r <= R){
  34. num[nw] ++;
  35. add(rt,nw);
  36. return ;
  37. }
  38. int mid = l+r >> 1;
  39. if(L <= mid) insert(rt<<1,l,mid,L,R,nw);
  40. if(R > mid) insert(rt<<1|1,mid+1,r,L,R,nw);
  41. }
  42. int ans = 0;
  43. inline void set(int u){
  44. for(int i = head[u];i;i=G[i].next){
  45. if(--num[G[i].id] == 0) ++ ans;
  46. }head[u] = 0;
  47. }
  48. inline void modify(int rt,int l,int r,int pos){
  49. if(l == r){
  50. T[rt] = 0;set(rt);
  51. return ;
  52. }
  53. int mid = l+r >> 1;
  54. if(pos <= mid) modify(rt<<1,l,mid,pos);
  55. else modify(rt<<1|1,mid+1,r,pos);
  56. T[rt] = T[rt<<1] + T[rt<<1|1];
  57. if(T[rt] == 0) set(rt);
  58. }
  59. int main(){
  60. int n,m;read(n);read(m);
  61. for(int i=1;i<=n;++i) read(a[i]);
  62. build(1,1,n);int u,v;
  63. for(int i=1;i<=m;++i){
  64. read(u);read(v);
  65. insert(1,1,n,u,v,i);
  66. }
  67. int q;read(q);
  68. while(q--){
  69. read(u);u = (u + ans - 1) % n + 1;
  70. if(--a[u] == 0) modify(1,1,n,u);
  71. printf("%d\n",ans);
  72. }
  73. getchar();getchar();
  74. return 0;
  75. }

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

  1. bzoj 4631: 踩气球 线段树合并

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

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

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

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

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

  4. 【bzoj4631】踩气球 线段树

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

  5. BZOJ 4631 踩气球

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

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

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

  7. Bzoj 2752 高速公路 (期望,线段树)

    Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...

  8. BZOJ.3938.Robot(李超线段树)

    BZOJ UOJ 以时间\(t\)为横坐标,位置\(p\)为纵坐标建坐标系,那每个机器人就是一条\(0\sim INF\)的折线. 用李超线段树维护最大最小值.对于折线分成若干条线段依次插入即可. 最 ...

  9. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

随机推荐

  1. 【智力题】IO——行测、笔试、面试中遇到的

    昨天(05.23)下午去参加了明源软件的暑期实习宣讲+笔试,第一次听说这个行业,行业和笔试风格完全不一样啊,5道行测智力题+1个问答+ 斐波那契数列 + 洗牌算法(思想.流程图.代码),今年回来后线上 ...

  2. 九度OJ 1350:二叉树的深度 (二叉树)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1044 解决:614 题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长 ...

  3. polynomial time

    https://en.wikipedia.org/wiki/Time_complexity#Polynomial_time An algorithm is said to be of polynomi ...

  4. 我的Android进阶之旅------>解决 Error: ShouldNotReachHere() 问题

    在Android项目中创建一个包含main()方法的类,直接右键运行该类时会报如下错误: # # An unexpected error has been detected by Java Runti ...

  5. 'gbk' codec can't encode character '\xa0' in position 34: illegal multibyte sequence

    今天在爬某广告贼多的网站遇到的问题,简单记录下

  6. IBM db2安装好了以后,启动不了服务

    系统默认将Server服务禁用,开启这个服务就可以启动服务.

  7. vim 光标的移动和跳转文件的位置

    刚启动vim进入的就是命令模式 在命令模式下 h等于左箭头 j等于下箭头 k等于上箭头 l等于右箭头 想要多次移动可以使用30j或30↓向下移动30行 在命令模式下输入0跳到行头 在命令模式下输入$跳 ...

  8. Spark Structured Streaming框架(3)之数据输出源详解

    Spark Structured streaming API支持的输出源有:Console.Memory.File和Foreach.其中Console在前两篇博文中已有详述,而Memory使用非常简单 ...

  9. 【并查集】关押罪犯(BSOJ2809)

    Description S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨 气值”(一个正整 ...

  10. uboot 2013.01 代码简析(3)第二阶段初始化

    u-boot第二阶段初始化内容的入口函数是_main,_main位于arch/arm/lib/crt0.S文件中: _main函数中先为调用board_init_f准备初始化环境(设置栈指针sp和并给 ...