题目描述

输入

第一行包括两个正整数,N ,M ,分别表示线段树的宽以及询问次数。

以下N-1 行以先序遍历(dfs深搜顺序)描述一个小R线段树,每行一个正整数表示当前非叶子节点的 mid,保证每个节点L<=mid<=r 。

(因为叶子节点不需要mid ,所以在读入时走到叶子节点时回溯即可,所以共N-1 个mid ,而且保证1~N-1 各出现一次)

而后M 行每行包括两个正整数,L,r(1<=L<=r<=N) 描述一个要求区间定位的区间。

输出

M行每行包括一个正整数,表示给出的询问区间在给定的线段树上的区间定位个数。

样例输入

7 3

4

3

1

2

5

6

3 6

2 7

1 6

样例输出

4

3

3

数据范围

样例解释



给定线段树样子如上图。

区间[3,6] 定位出的区间是[3,3][4,4][5,5][6,6] ,共四个。

区间[2,7] 定位出的区间是[2,3],[4,4],[5,7] ,共三个。

区间[1,6] 定位出的区间是[1,4],[5,5],[6,6] ,共两个。

解法

性质:[l,r]的答案=(r-l+1)*2-k (k为[l,r]包含的线段数)

证明:对于线段树里面的线段[l1,r1],这个线段所包含的线段共(r1-l1+1)*2-1。

[l,r]的答案=[l,r]中包含的极大线段,其中每个极大线段都会贡献(r1-l1+1)*2-1个线段被区间包含。

假设[l,r]中有n条极大线段,那么[l,r]所包含的线段就有(r-l+1)*2-n条。

所以n=(r-l+1)*2-[l,r]包含的线段数。

实现:排序后使用树状数组统计区间包含的线段数。

代码

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<math.h>
  4. #include<string.h>
  5. #include<algorithm>
  6. #define ll long long
  7. #define ln(x,y) int(log(x)/log(y))
  8. #define sqr(x) ((x)*(x))
  9. using namespace std;
  10. const char* fin="aP3.in";
  11. const char* fout="aP3y.out";
  12. const int inf=0x7fffffff;
  13. const int maxn=100007,maxm=maxn*2;
  14. int n,m,i,j,k,l,r,tot,mid,deep;
  15. struct qj{
  16. int l,r,id;
  17. }a[maxm],stack[maxm],b[maxm];
  18. int cd[maxm],ha[maxm];
  19. int c[maxn],ans[maxm];
  20. void add(int a1,int b,int c){
  21. if (c==1) {
  22. a[++tot].l=a1;
  23. a[tot].r=b;
  24. }
  25. if (a1==b) return ;
  26. stack[++deep].l=a1;
  27. stack[deep].r=b;
  28. cd[deep]=c;
  29. }
  30. bool cmp(qj a,qj b){
  31. return a.l<b.l;
  32. }
  33. void change(int v,int v1){
  34. for (;v<=n;v+=v&(-v)) c[v]+=v1;
  35. }
  36. int getsum(int v){
  37. int k=0;
  38. for (;v;v-=v&(-v)) k+=c[v];
  39. return k;
  40. }
  41. int main(){
  42. scanf("%d%d",&n,&m);
  43. add(1,n,1);
  44. while (deep){
  45. if (cd[deep]==1){
  46. scanf("%d",&ha[deep]);
  47. deep--;
  48. add(stack[deep+1].l,stack[deep+1].r,0);
  49. add(stack[deep].l,ha[deep],1);
  50. }else{
  51. deep--;
  52. add(ha[deep+1]+1,stack[deep+1].r,1);
  53. }
  54. }
  55. sort(a+1,a+tot+1,cmp);
  56. for (i=1;i<=m;i++){
  57. scanf("%d%d",&b[i].l,&b[i].r);
  58. b[i].id=i;
  59. }
  60. sort(b+1,b+m+1,cmp);
  61. j=tot;
  62. k=m;
  63. for (i=n;i>=1;i--){
  64. while (j && i==a[j].l) change(a[j--].r,1);
  65. while (k && i==b[k].l) {
  66. ans[b[k].id]=2*(b[k].r-b[k].l+1)-getsum(b[k].r);
  67. k--;
  68. }
  69. }
  70. for (i=1;i<=m;i++) printf("%d\n",ans[i]);
  71. return 0;
  72. }

启发

计算答案时:

1.答案由什么构成。

2.本题中什么东西易求。

3.把1中的东西转化为2中的求得答案。

例如本题:

1.显然[l,r]的答案即为包含的极大线段数。

2.[l,r]的所包含的线段数容易求得。

3.极大线段数=(r-l+1)*2-[l,r]的所包含的线段数。

完成转化,本题解决。

【JZOJ4747】【NOIP2016提高A组模拟9.3】被粉碎的线段树的更多相关文章

  1. JZOJ 4732. 【NOIP2016提高A组模拟8.23】函数

    4732. [NOIP2016提高A组模拟8.23]函数 (Standard IO) Time Limits: 1500 ms  Memory Limits: 262144 KB  Detailed ...

  2. 【NOIP2016提高A组模拟9.14】数列编辑器

    题目 分析 比赛上,没有注意到询问只询问光标前面,于是只打了个暴力. 因为询问只询问光标前面,首先,当光标向后每移动到一个位置,顺便将这个位置的前缀和,和最大前缀和求出来. 总之,模拟 #includ ...

  3. 【NOIP2016提高A组模拟9.24】总结

    第一题纯模拟,结果那个出题人脑子似乎进水了,空间限制开了1G!!! 导致我捉摸了半天为什么空间要开那么大,最后只能得出上面的结论. 第二题是个矩阵快速幂,比赛上我没把递推式求出来,但是根据各种乱搞,得 ...

  4. 【JZOJ4746】【NOIP2016提高A组模拟9.3】树塔狂想曲

    题目描述 相信大家都在长训班学过树塔问题,题目很简单求最大化一个三角形数塔从上往下走的路径和.走的规则是:(i,j)号点只能走向(i+1,j)或者(i+1,j+1).如下图是一个数塔,映射到该数塔上行 ...

  5. 【JZOJ4745】【NOIP2016提高A组模拟9.3】看电影

    题目描述 听说NOIP2016大家都考得不错,于是CCF奖励省常中了 K 张变形金刚5的电影票奖励OI队的同学去看电影.可是省常中OI队的同学们共有 N(N >= K)人.于是机智的你想到了一个 ...

  6. 【JZOJ4803】【NOIP2016提高A组模拟9.28】求导

    题目描述 输入 输出 样例输入 2x^2+3x+1 样例输出 4x+3 数据范围 样例解释 求导的意思: 多项式是由若干个单项式构成的 单项式的一般形式是ax^b,其中ab都是常数,x是自变量 对于单 ...

  7. 【JZOJ4787】【NOIP2016提高A组模拟9.17】数格子

    题目描述 输入 输出 样例输入 1 10000 3 10000 5 10000 0 0 样例输出 1 11 95 数据范围 每个测试点数据组数不超过10组 解法 状态压缩动态规划. 设f[i][j]表 ...

  8. [jzoj 4668] [NOIP2016提高A组模拟7.19] 腐败 解题报告(质数分类+慢速乘)

    题目链接: http://172.16.0.132/senior/#main/show/4668 题目: 题解: 考虑把A数组里的每个元素分解质因数,对于每个质因数开一个vector存一下包含这个质因 ...

  9. [jzoj 4722] [NOIP2016提高A组模拟8.21] 跳楼机 解题报告 (spfa+同余)

    题目链接: http://172.16.0.132/senior/#main/show/4722 题目: DJL为了避免成为一只咸鱼,来找srwudi学习压代码的技巧.Srwudi的家是一幢h层的摩天 ...

随机推荐

  1. [JSOI2010]连通数 (dfs或tarjan或bitset)+bitset学习

    题目描述 输入格式 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示无边. 输出格式 输出一行一个整数,表示该图的连通数. 样例 样 ...

  2. kill 3000

    杀3000端口,是作为一个web未开发人员经常遇到的事情 所以我今天就分享一下我的杀3000端口秘诀 lsof -i: 先要找到端口 node zcool 20u IPv6 0xdddbb4f6f12 ...

  3. 通过Angular-cli创建新项目

    前提:已经安装Git 方法一:(推荐) 1.在需要创建项目的文件夹中右键打开 Git Bush Here ,在此输入  ng new ‘项目名’  --skip-install   (如下my-app ...

  4. pycharm 汉化补丁

    找了很久,找到了这个比较好的pycharm汉化补丁包,就分享出来 1. 将解压包解压出来 2 . 复制对应的汉化补丁包到 x:\xxx\JetBrains\PyCharm Community Edit ...

  5. Python configparser的使用 读取配置文件

    configparser是Python自带用于读取配置文件的工具包,它的使用非常简单 配置文件 配置文件[]中为section命名,section的命名可以包含空格,每个section下面以键值对的方 ...

  6. mysql中not in子查询不能为空

    转载自:https://blog.csdn.net/headingalong/article/details/77744755 错误sql delete from company_info where ...

  7. 1.开始Springboot 基本配置和helloworld

    1 pom.xml 首先引入两个xml节点 <!--这里面继承了springboot很多相关依赖--> <parent> <groupId>org.springfr ...

  8. Win7+AMD+VS2013+opencl1.x安装与测试

    参考资料:http://www.cnblogs.com/lihao602/archive/2013/05/08/3067239.html: http://blog.csdn.net/zhoubo616 ...

  9. 作业-[luogu4396][AHOI2013]-莫队

    <题面> 卡常终究比不上算法的优化…… 这是莫队的有点小坑的题, 首先不一定能想到,想到不一定打对,打对不一定打好. 首先你会发现,这个题的时限是很长的- $n$和$m$也是很大的. 于是 ...

  10. ACdream 1112

    题目链接 Alice and Bob Time Limit: 6000/3000MS (Java/Others)Memory Limit: 256000/128000KB (Java/Others) ...