纠结了好久的一道题,以前是用线段树套平衡树二分做的,感觉时间复杂度和分块差不多了。。。

终于用BIT套函数式线段树了过了,120ms就是快,此题主要是卡内存。

假设离散后有ns个不同的值,递归层数是log2(ns)左右,nlog(ns),主席树是前缀区间,BIT保存修改的值是mlog2(ns)log2(ns)。

虽然这个算出来还是会爆,但是实际上会有一些结点复用,具体设置多少请相信玄学。(2e6左右)

ZOJ的Node*计算内存似乎有问题,必须用int

/*********************************************************
* ------------------ *
* author AbyssFish *
**********************************************************/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
//#pragma pack(4) const int MAX_N = 5e4+;
const int MAX_M = 1e4+;
const int MAX_NM = MAX_N+MAX_M;
const int MAX_D = ;
const int MAX_ND = 0xac*MAX_M+0x42fed;//MAX_D*MAX_N+MAX_M*MAX_D*MAX_D; int b[MAX_NM];
int mp_a[MAX_NM]; int ns, n_; int N, M; struct Cmd
{
int i, j, k;
}qus[MAX_M]; struct Node
{
int lc, rc;
int s;
}p[MAX_ND]; int root[MAX_N];
int cnt; #define lsn p[o].lc,l,md
#define rsn p[o].rc,md+1,r void build(int x,int &o,int l = , int r = ns)
{
p[++cnt] = p[o];
o = cnt;
p[o].s++;
if(r > l){
int md = (l+r)>>;
if(x <= md) build(x,lsn);
else build(x,rsn);
}
} int BIT[MAX_N]; void inst(int x, int d, int &o, int l = , int r = ns)
{
if(o == ){
p[++cnt] = p[o];
o = cnt;
}
p[o].s += d;
if(l < r){
int md = (l+r)>>;
if(x<=md) inst(x,d,lsn);
else inst(x,d,rsn);
} } #define lowbit(x) ((x)&(-x)) void modify_bit(int pos, int x, int d)
{
while(pos <= N){
inst(x,d,BIT[pos]);
pos += lowbit(pos);
}
} typedef vector<int> Prefix; void prefix_bit(int pos, Prefix &res)
{
res.clear();
while(pos > ){
res.push_back(BIT[pos]);
pos -= lowbit(pos);
}
} inline int cal_lft(Prefix &pfx)
{
int re = ;
for(int i = pfx.size()-; i >= ; i--){
re += p[p[pfx[i]].lc].s;
}
return re;
} #define dump(pfx,ch)\
for(i = pfx.size()-; i >= ; i--){\
pfx[i] = p[pfx[i]].ch;\
} Prefix X, Y; int qkth(int k,int l = , int r = ns)
{
if(l == r) return mp_a[l];
else {
int l_cnt = cal_lft(Y)-cal_lft(X);
int md = (l+r)>>, i;
if(k <= l_cnt){
dump(X,lc)
dump(Y,lc)
return qkth(k,l,md);
}
else {
dump(X,rc)
dump(Y,rc)
return qkth(k-l_cnt,md+,r);
}
} } void solve()
{
cnt = ;
memset(BIT+,,sizeof(int)*N);
int i;
for(i = ; i <= N; i++){
root[i] = root[i-];
build(b[i], root[i]);
} for(i = ; i < M; i++){
if(qus[i].j < ){
int pos = qus[i].i;
modify_bit(pos,b[pos],-);
modify_bit(pos,b[pos] = b[qus[i].k],);
}
else {
int L = qus[i].i-, R = qus[i].j;
prefix_bit(L,X);
prefix_bit(R,Y);
X.push_back(root[L]);
Y.push_back(root[R]);
printf("%d\n",qkth(qus[i].k));
}
}
} int * const a = (int *)(p+);
int * const r = a + MAX_NM; void init()
{
scanf("%d%d",&N,&M);
for(int i = ; i <= N; i++){
scanf("%d",a+i);
r[i] = i;
} n_ = N;
char ch[];
for(int i = ; i < M; i++){
scanf("%s",ch);
if(*ch == 'Q') {
scanf("%d%d%d",&qus[i].i,&qus[i].j,&qus[i].k);
}
else {
qus[i].k = ++n_;
r[n_] = n_;
scanf("%d%d",&qus[i].i,a+n_);
qus[i].j = -;
}
} sort(r+,r+n_+,[](int i,int j){ return a[i]<a[j]; });
mp_a[b[r[]] = ns = ] = a[r[]];
for(int i = ; i <= n_; i++) {
int k = r[i];
if(a[k] != a[r[i-]]){
mp_a[b[k] = ++ns] = a[k];
}
else {
b[k] = ns;
}
}
} //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
//cout<<ceil(log2(MAX_N+MAX_M))+1;
//cout<<sizeof(Node*)<<endl;
//cout<<MAX_ND<<endl;
// cout<<MAX_ND*sizeof(Node)+(MAX_NM)*16+MAX_M*12+MAX_N*8;
// cout<<sizeof(a)+sizeof(root)+sizeof(meo)+sizeof(qus)+sizeof(BIT)<<endl;//sizeof(b)+sizeof(mp_a)+sizeof(r)
p[] = {,,};
X.reserve(MAX_D+);
Y.reserve(MAX_D+); int T; scanf("%d",&T);
while(T--){
init();
solve();
}
return ;
}

ZOJ - 2112 Dynamic Rankings(BIT套主席树)的更多相关文章

  1. ZOJ 2112 Dynamic Rankings(二分,树套树)

    动态区间询问kth,单点修改. 区间用线段树分解,线段树上每条线段存一颗平衡树. 不能直接得到kth,但是利用val和比val小的个数之间的单调性,二分值.log^3N. 修改则是一次logN*log ...

  2. bzoj1901: Zju2112 Dynamic Rankings(BIT套主席树)

    带修改的题主席树不记录前缀,只记录单点,用BIT统计前缀.  对于BIT上每一个点建一棵主席树,修改和询问的时候用BIT跑,在主席树上做就行了.  3k4人AC的题#256...应该不算慢 #incl ...

  3. 主席树[可持久化线段树](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 ...

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

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

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

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

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

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

  7. ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解

    题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...

  8. ZOJ 2112 Dynamic Rankings(树状数组+主席树)

    题意 \(n\) 个数,\(m\) 个操作,每次操作修改某个数,或者询问某个区间的第 \(K\) 小值. \(1 \leq n \leq 50000\) \(1 \leq m \leq 10000\) ...

  9. BZOJ 1901 洛谷 P2617 ZOJ 2112 Dynamic Rankings

    以下时空限制来自zoj Time limit 10000 ms Memory limit 32768 kB OS Linux Source Online Contest of Christopher' ...

  10. ZOJ 2112 Dynamic Rankings (动态第k大,树状数组套主席树)

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

随机推荐

  1. 自动截取sql并合并,生成执行HQL

    ### 提取SQL语句 FILE_PATH="/data/SCRIPT" cat tables | while read file do echo "-----> ...

  2. 数据结构---Java---有序数组

    [自定义有序数组] 查找算法: 线性查找算法:依次对比查询: 二分查找算法:必须是有序: insert:要插入的value与数组中每个元素进行比较,当有值>value时,此处的index之后的元 ...

  3. 获取url传的参数转变为对象的方法

    function GetRequest() { var url = location.search; //获取url中"?"符后的字串 var theRequest = new O ...

  4. Linux下wget下载软件小技巧以及安装jdk、tomcat与ftp服务器

    一.ftp的安装 装个ftp搞了一下午,感觉以前没那么麻烦的呀,结果到晚上才发现是实验室网的问题,换连手机的热点马上可以了,真是尴尬,把基本安装步骤记录一下: 1.检查安装vsftpd软件 使用如下命 ...

  5. BaseAdapter,SimpleAdapter,CursorAdapter的用法

    简单好用的Adapter---ArrayAdapter ArrayAdapter是BaseAdapter的派生类,在BaseAdapter的基础上,添加了一项重大的功能:可以直接使用泛型构造. 我们先 ...

  6. 跟我一起用python画你所想吧!

    0.库的引入 要想画图,我们先倒入两个库. import numpy as np import matplotlib.pyplot as plt 注:以下代码全都基于导入这两个库的前提下编写的. 1. ...

  7. [转]【无私分享:ASP.NET CORE 项目实战(第十四章)】图形验证码的实现

    本文转自:http://www.cnblogs.com/yuangang/p/6000460.html 目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 很长时间没有来更新博客 ...

  8. 二维码项目实例为二维码添加logo

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  9. Lync二次开发关于Lync启动退出问题

    以前使用C++开发的version.dll文件,由于各个用户环境的不同,造成某些用户加载不了我们开发的插件,并且写version.dll的同事还没找到好的解决办法,所以得换一种思路去解决这个问题,就是 ...

  10. Struts_ActionWildcard_通配符配置

    使用通配符,将配置量降到最低 不过,一定要遵守“约定由于配置”的原则 struts2.xml <?xml version="1.0" encoding="UTF-8 ...