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

终于用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. mybatis CDATA引起的查询失败

    <![CDATA[ ]]> 在被CDATA包围的所有字符串不会被mybatis解析, 直接写入sql了 CDATA应该只用在特殊字符前后,不能用在<if> <foreac ...

  2. 在word2010中添加带滚动条的文本框

    由于文件内容过长,为了加强文章的可读性,可以添加一个带滚动条的文本框,既能使文章看起来干净整洁,同时也极大的提高了文章的可读性. 我这里对在word2010中文本框带滚动条作个介绍: 1. 打开wor ...

  3. C#学习 - 关于Interlocked.CompareExchange()的用法

    https://blog.csdn.net/jianhui_wang/article/details/80485517 Interlocked.CompareExchange有一组函数   名称 说明 ...

  4. 5-----BBS论坛

    BBS论坛(五) 5.1.cms后台修改密码功能完成 (1)新建app/forms.py # app/forms.py from wtforms import Form class BaseForm( ...

  5. 2----scrapy框架之代理and日志级和请求传参

    一.代理 爬虫文件 daili.py class DailiSpider(scrapy.Spider): name = 'daili' #allowed_domains = ['www.xxx.com ...

  6. android window(二)从getSystemService到WindowManagerGlobal

    在Activity调用getSystemService(WINDOW_SERVICE) 调用的是父类ContextThemeWrapper package android.view; public c ...

  7. 在IE8下background-image不显示的解决方法

    刚写一个页面,在chrome,FF里调试完后,忽然想起ie来,放到Ie里其它还好了,但是有个背景图片显示不出来. 调试N遍后,只好上stackoverflow去找一下,果然找到了. 最初是这样写的: ...

  8. [转]JS判断访问设备、客户端操作系统类型

    本文转自:http://www.cnblogs.com/duanguyuan/p/3534470.html 先给出一个实例:判断windows.linux.android 复制以下代码另存为html文 ...

  9. Windows64bit-plsqldeveloper-install the easiest way

    The easiest way to add a 32 Bit Oracle Client: 1.Download the Oracle 11g or 12c Instant Client(http: ...

  10. java.lang.IllegalStateException: FragmentManager is already executing transactions 及 SmartTabLayout复用

    在复用 SmartTabLayout  时, 出现了标题所示的错误.首先我的场景是Activity下两个fragment  :A 和 B,A中使用了SmarttabLayout和viewpager结合 ...