Time:2016.05.09
Author:xiaoyimi
转载注明出处谢谢


传送门1
传送门2
思路:
之前没怎么接触过权值线段树(非主席树),这次就当学习了一下吧。一开始还把题意理解错了,我的天啊……
起初思考了好久,发现不知道怎么处理负数的情况,不过数据里并没有负数?
权值线段树的每个节点表示一个区间[L,R],存储原序列中权值为[L,R]的元素的信息,所以这里的权值线段树每个节点上都是一棵普通线段树,就是负责统计原序列中权值为[L,R]的元素的个数。
每次插入一个相同的值x时就相当于在权值线段树上从根节点一直向下到x所代表的叶子节点,每到权值线段树上的一个节点就修改这个节点所存储的普通线段树的信息
查询时利用二分思想即可(可参见主席树相关练习),但是这里是查询第K大,所以每次折半时计算右子树大小,K大于它就找左边,不然就找右边
注意:
1.代码中采用了标记永久化思想,压小了常数,不过这是我第一次学习使用这个特殊技巧,感觉有些生疏,以后还是要多加练习
(感觉网上对于这个技巧讲述的不多啊!要是那天我熟练了这个技巧了,来写一篇吧
2.BZOJ上计算总和要无符号整型,不然会爆int,我的天啊……
代码:

#include<bits/stdc++.h>
#define M 50005
#define ul unsigned int
using namespace std;
int n,m,cnt_S,cnt_V,root_S[M<<4],root_V;
struct Segment_tree
{ul sum,lazy;int ch[2];
}S[M*300];
struct Value_tree
{int ch[2];
}V[M];
int in()
{int t=0,f=1;char ch=getchar();while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)) t=(t<<3)+(t<<1)+ch-48,ch=getchar();return f*t;
}
void S_change(int &rt,int begin,int end,int l,int r)
{if (!rt) rt=++cnt_S;if (l<=begin&&end<=r){S[rt].sum+=end-begin+1;S[rt].lazy++;return;}int mid=begin+end>>1;if (mid>=l) S_change(S[rt].ch[0],begin,mid,l,r);if (mid<r)  S_change(S[rt].ch[1],mid+1,end,l,r);S[rt].sum=S[S[rt].ch[0]].sum+S[S[rt].ch[1]].sum+S[rt].lazy*(end-begin+1);
}
ul S_get(int &rt,int begin,int end,int l,int r)
{if (!rt) return 0;if (l<=begin&&end<=r) return S[rt].sum;int mid=begin+end>>1;ul ans=S[rt].lazy*(min(r,end)-max(l,begin)+1);if (mid>=l) ans+=S_get(S[rt].ch[0],begin,mid,l,r);if (mid<r)  ans+=S_get(S[rt].ch[1],mid+1,end,l,r);return ans;
}
void V_change(int &rt,int begin,int end,int x,int y,int z)
{if (!rt) rt=++cnt_V;S_change(root_S[rt],1,n,x,y);if (begin==end) return;int mid=begin+end>>1;if (mid>=z)V_change(V[rt].ch[0],begin,mid,x,y,z);elseV_change(V[rt].ch[1],mid+1,end,x,y,z);
}
int V_get(int rt,int begin,int end,int x,int y,int z)
{if (begin==end) return end;int mid=begin+end>>1;ul t=S_get(root_S[V[rt].ch[1]],1,n,x,y);if (z<=t)return V_get(V[rt].ch[1],mid+1,end,x,y,z);elsereturn V_get(V[rt].ch[0],begin,mid,x,y,z-t);
}
main()
{n=in();m=in();int opt,x,y,z;while (m--){opt=in();x=in();y=in();z=in();if (opt==1) V_change(root_V,1,n,x,y,z);else printf("%lu\n",V_get(root_V,1,n,x,y,z));}
}

【BZOJ3110】【codevs1616】K大数查询,权值线段树套普通线段树相关推荐

  1. BZOJ3110: [Zjoi2013]K大数查询

    BZOJ3110: [Zjoi2013]K大数查询 Description 有N个位置,M个操作. 操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如 ...

  2. bzoj3110 [Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 10703  Solved: 3209 [Submit][ ...

  3. [BZOJ3110] [Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 9208  Solved: 2737 [Submit][S ...

  4. bzoj3110: [Zjoi2013]K大数查询 【树套树,标记永久化】

    //========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明! //=============== ...

  5. BZOJ3110: [Zjoi2013]K大数查询(整体二分)

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  6. bzoj 3110: [Zjoi2013]K大数查询(树套树)

    树套树: 本质:一棵树的每个节点套着另一棵树 通常时间复杂度:O(nlog²n) 空间复杂度:因为树的大小是nlogn,而每个节点又有一棵nlogn的树,所以最大空间复杂度为O(n²log²) 但事实 ...

  7. 3110: [Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询 https://lydsy.com/JudgeOnline/problem.php?id=3110 分析: 整体二分+线段树. 两种操作:区间加入一个数,区 ...

  8. 洛谷 P3332 [ZJOI2013]K大数查询 解题报告

    P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ...

  9. P3332 [ZJOI2013]K大数查询(整体二分做法)

    P3332 [ZJOI2013]K大数查询 题意: 题解: 利用整体二分来做,这个题和P3834 [模板]可持久化线段树 2的区别在于本题的修改是区间修改,所以将里面的树状数组改成线段树就行,区间修改 ...

  10. java 蓝桥杯 算法训练 区间k大数查询(题解)

    试题 算法训练 区间k大数查询 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示 ...

最新文章

  1. git add remote_Git每次更新提交都提示输入密码怎么解决?
  2. Linux快捷键-命令行下
  3. 20155222卢梓杰 课堂测试ch06补做
  4. java求面积Shape类_Shape-2,形状类,正方形类,长方形类,圆类,求周长面积
  5. “设为桌面图标”的ASP源代码
  6. MyBatis笔记——EhCache二级缓存
  7. java注销对话框_【java小程序实战】小程序注销功能实现
  8. php-fpm7.0,php-fpm7.0 慢查询设置及说明
  9. 听说你盗图都盗绿了?
  10. Bootstrap-点击“×”,可以关闭页面
  11. scala学习笔记一------初步了解scala
  12. Android系统源码目录解析
  13. java 3dm_3dm游戏运行库合集安装包-游戏运行库合集安装包下载v3.0DM整理-西西软件下载...
  14. 华为HG8145C获取超级密码
  15. 家庭收支记账软件Java
  16. Acer 4250G TL 58 Vista 系统装xp系统完全攻略
  17. 微带线特性阻抗计算公式_几种计算微带线特性阻抗的方法.pdf
  18. SIGHUP信号与控制终端
  19. Redis INCR命令
  20. 中国保温杯市场销售渠道分析与营销模式报告(2021-2026年)

热门文章

  1. python17个常见问题_Python 常见的17个错误分析
  2. ubuntu php mysql apache_Ubuntu+Apache+PHP+Mysql环境搭建(完整版)(转)
  3. Android笔记 get方式提交数据到服务器 避免乱码 demo
  4. navicat将远程数据库复制到本地数据库方法
  5. Spark 【数据挖掘平台介绍】 - Spark 1.1.0(看范式粒度)
  6. Python练习:合格率的计算
  7. 中文linux最小,35M的中文linux硬盘简单安装方法Live-CD:SliTaz.tw-全世界最小的li
  8. Eclipse快捷键的使用
  9. mysql常用的备份命令有哪些_MySQL常用备份还原命令
  10. python123百钱买百鸡_day01笔记-百钱买百鸡(100文钱,必须买100只鸡,有几种方式)