以下时空限制来自zoj
Time limit 10000 ms
Memory limit 32768 kB
OS Linux
Source Online Contest of Christopher's Adventure
Author XIN, Tao

吐槽

zoj卡空间卡得太死了……32MB,远远不够放没优化过的主席树套树状数组……刚开始时段错误,还以为是t数组没开够,还是学得不扎实,别人说是就是,都没自己想想算算……后来二分骗数据,发现在还没开始操作、正在建最初的主席树时空间就爆了。没有优化的主席树,t数组要开到N*100左右,但这题最多给开到N*40……所以逼着我们优化空间。

平台 n m 空间限制
洛谷 1e5 1e5 1000MB
BZOJ 1e4 1e4 128MB
ZOJ 5e4 1e4 32MB

解题思路

  1. 分块+二分查找 https://blog.csdn.net/qq_35320178/article/details/81077787
  2. 整体二分、cdq分治 https://www.cnblogs.com/ScratchingBear/p/5345820.html
  3. 线段树套平衡树、权值线段树套平衡树 https://blog.csdn.net/htt_h/article/details/47701417
  4. 树状数组套主席树 https://www.cnblogs.com/Empress/p/4659824.html
    • 这篇博客讲得是真的好,垃圾百度把它排到贼靠后

源代码

这个是我在BZOJ(本机测的darkbzoj数据,把N和M改小即可)、洛谷上的AC代码,主要参考洛谷zsy的题解。ZOJ的留坑,打算把优化空间的方法、整体二分、cdq分治学了。

// luogu-judger-enable-o2
#include<stdio.h>
#include<string.h>
#include<algorithm>
const int N=100010,M=100010;
int T;
int n,m;
int a[N];
struct Opt{
char mode;
int l,r,k;
}opt[M]; int val[N+M],sz;
int id(int x){return std::lower_bound(val+1,val+sz+1,x)-val;} struct Node{
int lson,rson;
long long sum;
}t[N*400];
int root[N],cnt=0; int inline lowbit(int x){return x&-x;} void update_tree(int &x,int l,int r,int pos,int k)
{//pre好像不需要啊,第x个节点的值并不用从pre继承过来,因为套上树状数组以后就不是前缀和了。参考zsy博客
if(!x) x=cnt++;//x等于0说明还没分配过
t[x].sum+=k;
if(l==r) return;
int mid=l+r>>1;
if(pos<=mid) update_tree(t[x].lson,l,mid,pos,k);
else update_tree(t[x].rson,mid+1,r,pos,k);
}
void change(int pos,int k)//数字a[pos]数量加k(先把之前的值去掉)
{
int value=id(a[pos]);
for(int i=pos;i<=n;i+=lowbit(i))
update_tree(root[i],1,sz,value,k);
}
int temp[2][20];
//记录询问时需要统计的节点编号,因为根有root数组,可以root[x-lowbit(x)],但下来的儿子孙子节点不能,所以先把需要统计的根记录在temp数组中,然后统计完一层以后将temp数组记录的节点向下挪动。
//temp[0]记录第l-1棵线段树上的节点编号,temp[1]记录第r棵线段树上的节点编号。
//由于节点已经存到temp中了,所以que_tree函数的参数就少了很多了。
int que_tree(int l,int r,int k)
{
if(l==r) return l;
int mid=l+r>>1,delta=0;
for(int i=1;i<=temp[1][0];i++) delta+=t[t[temp[1][i]].lson].sum;
for(int i=1;i<=temp[0][0];i++) delta-=t[t[temp[0][i]].lson].sum;//统计那几棵树的左儿子的sum,用来和k比较,找出从左还是从右
if(k<=delta)//向左走
{
for(int i=1;i<=temp[0][0];i++) temp[0][i]=t[temp[0][i]].lson;
for(int i=1;i<=temp[1][0];i++) temp[1][i]=t[temp[1][i]].lson;//temp也向下走
return que_tree(l,mid,k);
}
else
{
for(int i=1;i<=temp[0][0];i++) temp[0][i]=t[temp[0][i]].rson;
for(int i=1;i<=temp[1][0];i++) temp[1][i]=t[temp[1][i]].rson;
return que_tree(mid+1,r,k-delta);
} } int que(int l,int r,int k)
{
temp[0][0]=temp[1][0]=0;//用于统计temp[0]和temp[1]中存了多少个节点下标
for(int i=l-1;i;i-=lowbit(i))
temp[0][++temp[0][0]]=root[i];
for(int i=r;i;i-=lowbit(i))
temp[1][++temp[1][0]]=root[i];
return que_tree(1,sz,k);
}
/******************调试代码******************/
//用于输出主席树上每棵线段树所代表的序列
int quesum(int x,int l,int r,int pos)
{
if(l==pos&&pos==r) return t[x].sum;
int mid=l+r>>1;
if(pos<=mid) return quesum(t[x].lson,l,mid,pos);
else return quesum(t[x].rson,mid+1,r,pos);
}
inline void debug()
{
for (int i = 1; i <= sz; i++)
printf("%d ", val[i]);
puts("\n****************");
for (int rt = 0; rt <= n; rt++, puts(""))
for (int i = 1; i <= sz; i++)
printf("%d ", quesum(root[rt], 1, sz, i));
puts("******************");
}
/*******************调试代码完*****************/
int main()
{
//freopen("test.in","r",stdin);
//scanf("%d",&T);
//while(T--)
{
sz=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",a+i),val[++sz]=a[i];
for(int i=1;i<=m;i++)
{
char mode[2];
int l,r,k;
scanf("%s",mode);
if(mode[0]=='Q')
{
scanf("%d%d%d",&l,&r,&k);
opt[i]={mode[0],l,r,k};
}
else
{
scanf("%d%d",&l,&k);
opt[i]={mode[0],l,0,k};
val[++sz]=k;
}
} std::sort(val+1,val+1+sz);
sz=std::unique(val+1,val+sz+1)-val-1; //memset(root,0,sizeof(root));
//memset(t,0,sizeof(t));
cnt=1;
for(int i=1;i<=n;i++)
change(i,1);
//debug();
for(int i=1;i<=m;i++)
{
if(opt[i].mode=='Q')
{
printf("%d\n",val[que(opt[i].l,opt[i].r,opt[i].k)]);
}
else
{
change(opt[i].l,-1);
a[opt[i].l] = opt[i].k;
change(opt[i].l,1);
//debug();
}
}
}
return 0;
}

BZOJ 1901 洛谷 P2617 ZOJ 2112 Dynamic Rankings的更多相关文章

  1. ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)

    题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...

  2. 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )

    在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...

  3. 整体二分(SP3946 K-th Number ZOJ 2112 Dynamic Rankings)

    SP3946 K-th Number (/2和>>1不一样!!) #include <algorithm> #include <bitset> #include & ...

  4. 整体二分&cdq分治 ZOJ 2112 Dynamic Rankings

    题目:单点更新查询区间第k大 按照主席树的思想,要主席树套树状数组.即按照每个节点建立主席树,然后利用树状数组的方法来更新维护前缀和.然而,这样的做法在实际中并不能AC,原因即卡空间. 因此我们采用一 ...

  5. ZOJ 2112 Dynamic Rankings(主席树の动态kth)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 The Company Dynamic Rankings ...

  6. 高级数据结构(树状数组套主席树):ZOJ 2112 Dynamic Rankings

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  7. ZOJ 2112 Dynamic Rankings(带修改的区间第K大,分块+二分搜索+二分答案)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  8. ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大

    Dynamic Rankings 带修改的区间第K大其实就是先和静态区间第K大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树 ...

  9. zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap

    Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...

随机推荐

  1. 联盟周赛2019810 csgo (动态规划、不下降子序列)

    今天起晚了...就做了俩题 难受的一批... 题目描述 著名第一人称射击游戏 csgo 因其优秀的平衡性,爽快的射击感和科学的战术配比赢得了世界广大玩家的好评. 在一局游戏中,分为两个阵营,他们的目标 ...

  2. Atomic实现原子性源码分析:CAS(比较并交换)、Unsafe类

    1.CAS: 比较并交换(Compare And Swap),是Unsafe类中的一条CPU系统原语,原语的执行必须是连续的,在执行过程中不允许被中断,即CAS是一条CPU的原子指令,不会造成数据不一 ...

  3. C++线性表通过结构体实现操作和结构体字符串快速排序和shell排序结合

    #include<iostream> #include<string> #define ml 10 using namespace std; typedef struct{// ...

  4. 在Vue项目中加载krpano全景图

    在Vue-cli项目中做krpano全景图编辑器的时候,由于js插件的路径是动态的,做的过程中遇到了加载不到资源的难题,在网上搜索了好久也没找到合适的办法,最后想到了可能是JS加载的问题,于是解决了问 ...

  5. Java Script 基本知识点

                          JavaScript是一种基于对象和事件驱动的脚本语言,它提供了一些专有的类.对象及函数 1.基本数据类型 JavaScript提供了4种基本的数据类型用来 ...

  6. Deepin安装 ruby 包管理工具 RVM(适用于 Debian 系列)

    1. 安装 GPG keys 先安装 gpg2 工具 sudo apt install gnupg2 再安装 keys gpg2 --recv-keys 409B6B1796C275462A17031 ...

  7. mybatis动态sql详情

    mybatis动态拼装sql详情 MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有: if choos ...

  8. Python操作Redis,你要的都在这了!

    Redis是一个基于内存的高效的键值型非关系型数据库,存取效率极高,而且支持多种存储数据结构,使用也非常简单.本节中,我们就来介绍一下Python的Redis操作,主要介绍RedisPy这个库的用法. ...

  9. ipcclean - 从退出的PostgreSQL服务器中删除共享内存和信号灯

    SYNOPSIS ipcclean DESCRIPTION 描述 ipcclean 删除当前用户拥有的所有共享内存段和信号灯集. 它的目地是在 PostgreSQL 服务器 (postmaster(1 ...

  10. Vue基础第三章 - 计算属性

    1.计算属性介绍 在第二章中我们介绍了在Vue的{{}}中可以使用一些简单的表达式进行计算,但是当表达式过长或者逻辑过于复杂就会变得不易理解和维护,比如第二章的示例{{ text.split(',') ...