BZOJ1901 Zju2112 Dynamic Rankings 主席树
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ1901
题意概括
给你一段序列(n个数),让你支持一些操作(共m次),
有两种操作,一种是询问区间第k小,一种是单点修改。
n,m<=10000
题解
这个主席树的写法是我自己造出来的。
主席树的查询区间第k大需要依赖前缀和。
树状数组最擅长这个了,就让他来干。
原理是这样的:
先离散化,包括修改操作里面的数字也要离散化。
然后建树,包括修改操作所涉及的数值也要建。
现在总共有n个线段树。
第0棵树是最完整的,故我们把这棵树的每一个节点都当作一个树状数组的起点,即该树状数组的第一项。
然后往下一棵树走,当然下一棵树不一定有这个节点,那么不停的走下去,这个可以在建树的时候预先处理一个Next数组来优化。
走到下一个这个位置的节点之后,我们再把这个节点作为该树状数组的第二项。
这样我们有大约n*4(第0棵树的节点个数)个树状数组了。
然而不处理要超空间。
所以有两种方案,一种是vector,一种是把所有的树状数组连起来,变成一个大的。
然而查询之类的就和普通的主席树差不多了。
细节上要大大的注意!
代码
- #include <cstring>
- #include <algorithm>
- #include <cstdio>
- #include <cstdlib>
- #include <cmath>
- #include <vector>
- using namespace std;
- const int N=10005,S=N*2*20*4;//v=4*node=4*20*hs=4*20*2*n
- struct Que{
- char op;
- int a,b,c;
- void read(){
- char opc[5];
- scanf("%s%d%d",opc,&a,&b);
- op=opc[0];
- if (op=='Q')
- scanf("%d",&c);
- }
- }q[N];
- vector <int> vec[N];
- int n,m,v[N],Ha[N*2],hs=0,total=0,totarr=0;
- int root[N],ls[S],rs[S],sum[S],pos[S],Next[S],p[S];
- void LSH(){
- int hs_=1;
- sort(Ha+1,Ha+hs+1);
- for (int i=2;i<=hs;i++)
- if (Ha[i]!=Ha[i-1])
- Ha[++hs_]=Ha[i];
- hs=hs_;
- }
- int find(int x){
- int L=1,R=hs,mid;
- while (L<=R){
- mid=(L+R)>>1;
- if (Ha[mid]==x)
- return mid;
- if (Ha[mid]<x)
- L=mid+1;
- else
- R=mid-1;
- }
- exit(233);
- }
- int build(int L,int R){
- int rt=++total;
- if (L==R){
- ls[rt]=rs[rt]=0;
- return rt;
- }
- int mid=(L+R)>>1;
- ls[rt]=build(L,mid);
- rs[rt]=build(mid+1,R);
- return rt;
- }
- int lowbit(int x){
- return x&-x;
- }
- void add(int x,int v){
- for (;x<=totarr;x+=lowbit(x))
- sum[x]+=v;
- }
- int Sum(int x){
- int ans=0;
- for (;x>0;x-=lowbit(x))
- ans+=sum[x];
- return ans;
- }
- void add_tree(int prt,int &rt,int L,int R,int pos){
- if (!rt||rt==prt)
- rt=++total;
- Next[prt]=rt;
- if (L==R)
- return;
- int mid=(L+R)>>1;
- if (pos<=mid){
- add_tree(ls[prt],ls[rt],L,mid,pos);
- if (!rs[rt])
- rs[rt]=rs[prt];
- }
- else {
- add_tree(rs[prt],rs[rt],mid+1,R,pos);
- if (!ls[rt])
- ls[rt]=ls[prt];
- }
- }
- void build_treearr(int srt,int L,int R){
- for (int i=srt;i;i=Next[i])
- p[i]=++totarr;
- if (L==R)
- return;
- int mid=(L+R)>>1;
- build_treearr(ls[srt],L,mid);
- build_treearr(rs[srt],mid+1,R);
- }
- void update(int rt,int L,int R,int pos,int v){
- add(p[rt],v);
- if (L==R)
- return;
- int mid=(L+R)>>1;
- if (pos<=mid)
- update(ls[rt],L,mid,pos,v);
- else
- update(rs[rt],mid+1,R,pos,v);
- }
- int query(int prt,int rt,int L,int R,int k){
- if (L==R)
- return Ha[L];
- int mid=(L+R)>>1;
- int LV=Sum(p[ls[rt]])-Sum(p[ls[prt]]);
- if (k<=LV)
- return query(ls[prt],ls[rt],L,mid,k);
- else
- return query(rs[prt],rs[rt],mid+1,R,k-LV);
- }
- int main(){
- scanf("%d%d",&n,&m);
- for (int i=1;i<=n;i++)
- scanf("%d",&v[i]),Ha[++hs]=v[i];
- for (int i=1;i<=m;i++){
- q[i].read();
- if (q[i].op=='C')
- Ha[++hs]=q[i].b;
- }
- LSH();
- for (int i=1;i<=n;i++)
- vec[i].clear();
- for (int i=1;i<=n;i++)
- vec[i].push_back(v[i]);
- for (int i=1;i<=m;i++)
- if (q[i].op=='C')
- vec[q[i].a].push_back(q[i].b);
- memset(sum,0,sizeof sum);
- memset(pos,0,sizeof pos);
- memset(Next,0,sizeof Next);
- memset(root,0,sizeof root);
- root[0]=build(1,hs);
- for (int i=1;i<=n;i++)
- for (int j=0;j<vec[i].size();j++)
- add_tree(root[i-1],root[i],1,hs,find(vec[i][j]));
- build_treearr(root[0],1,hs);
- for (int i=1;i<=n;i++)
- update(root[i],1,hs,find(v[i]),1);
- for (int i=1;i<=m;i++)
- if (q[i].op=='C'){
- update(root[q[i].a],1,hs,find(v[q[i].a]),-1);
- update(root[q[i].a],1,hs,find(v[q[i].a]=q[i].b),1);
- }
- else
- printf("%d\n",query(root[q[i].a-1],root[q[i].b],1,hs,q[i].c));
- return 0;
- }
BZOJ1901 Zju2112 Dynamic Rankings 主席树的更多相关文章
- 【BZOJ1901】Zju2112 Dynamic Rankings 主席树+树状数组
[BZOJ1901]Zju2112 Dynamic Rankings Description 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j ...
- Bzoj 1901: Zju2112 Dynamic Rankings 主席树,可持久,树状数组,离散化
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6321 Solved: 2628[Su ...
- bzoj 1901: Zju2112 Dynamic Rankings -- 主席树,树状数组,哈希
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1] ...
- [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】
题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...
- BZOJ1901 Zju2112 Dynamic Rankings 【树状数组套主席树】
题目 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[j]中第k小的数是多少(1≤k≤j- ...
- [bzoj1901][Zju2112]Dynamic Rankings_主席树
Dynamic Rankings bzoj-1901 Zju-2112 题目大意:给定一个n个数的序列,m个操作,支持:单点修改:查询区间k小值. 注释:$1\le n,m\le 10^4$. 想法: ...
- [BZOJ1901]Zju2112 Dynamic Rankings
[BZOJ1901]Zju2112 Dynamic Rankings 试题描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i ...
- BZOJ-1901 Zju2112 Dynamic Rankings 函数式线段树 套 树状数组+离线处理
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Submit: 6058 Solved: 2521 [Su ...
- bzoj1901: Zju2112 Dynamic Rankings(BIT套主席树)
带修改的题主席树不记录前缀,只记录单点,用BIT统计前缀. 对于BIT上每一个点建一棵主席树,修改和询问的时候用BIT跑,在主席树上做就行了. 3k4人AC的题#256...应该不算慢 #incl ...
随机推荐
- Spring XML配置里的Bean自动装配
Spring自动装配 这段是我们之前编写的代码,代码中我们使用了P命名空间 并且使用手动装配的方式将car <bean id="address" class="cn ...
- asp.net mvc url应用
//url加密与解密string res1 = HttpUtility.UrlEncode("7Z2K5Lgk/iI="); //值是7Z2K5Lgk%2fiI%3d string ...
- IO流总结笔记一
IO流继承关系图 IO概述 IO流是用来处理设备上数据的输入输出. 具体设备有:硬盘,内存,键盘录入等等. IO流的具体分类: 1,根据处理的数据类型不同分为:字节流和字符流,字节流读取的最小单位 ...
- Spring+CXF整合来管理webservice(服务器启动发布webservice)
Spring+CXF整合来管理webservice 实现步骤: 1. 添加cxf.jar 包(集成了Spring.jar.servlet.jar ),spring.jar包 ,serv ...
- TrimLeft TrimRight
strming.TrimLeft(); //将字符串最前面的空格修整掉.当在没有参数的情况下调用时,TrimLeft删除换行符,空格和tab字符. strming.TrimRight()://消除从 ...
- Django配置富文本编辑器kindeditor
一.简介 django是一个容易快速上手的web框架,用它来创建内容驱动型的网站(比如独立博客)十分方便.遗憾的是,django并没有提供官方的富文本编辑器,而后者恰好是内容型网站后台管理中不可或缺的 ...
- MR运动静止用户区分
1.客户端打开菜单[MR]-[MR室内室外判定设置] 设置主小区是室外站且主小区信号比较强时RSRP门限 2.设置"上报数据用户临小区切换次数门限设置"值为15 mysql中t_m ...
- python根据服务名获取服务启动路径
#coding=utf8 import _winreg as winreg class Win32Environment: """Utility class to get ...
- git 使用https 和SSH 提交远程库小总结
一.使用https提交远程库 首先已经git commit -m “注释” 本地仓库关联远程github服务器:git remote add origin “https://XXXX.git” 提交 ...
- Android通讯:通话
Android通讯之通话功能的实现: 在Android中,android.telephony.TelephonyManager对象是开发者获取当前通话网络相关信息的窗口,通过TelephonyMana ...