http://www.lydsy.com/JudgeOnline/problem.php?id=1901

首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊。

bzoj提交是wa!!T_T,将数组改大就acT_T

吐槽完毕。

这题之前做过,用树套树做的,但是时间感人(http://www.cnblogs.com/iwtwiioi/p/3870597.html

鉴于我是蒟蒻,所以我根本不会做啊!!

学习,,,

恩。。。

这题用树状数组来维护区间,写过树状数组套树的都应该会。和我之前的做法一样。

但是统计的话, 要多一步骤,就是将所有区间的主席树放进一个池子里面,然后才比较。

你懂得。

但是本题的重点不在这啊!!!

我也理解了很久。至于前面说的,本来就会了额。

离散化。。。很hentai。

我们首先要将所有的值都统计起来,因为主席树是离线的啊啊啊啊啊。。

然后用原来的方法离散确定区间。

然后询问没问题,另一个就是更新了。

不更新的主席树我们都会。更新的主席树照样很简单。

我们只要将原来的点删了,然后再补上。是不是很神奇啊。一点都不神奇,噗。

将原来点删了就是size-1。

然后你懂的。

一些东西写在代码里吧:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define lowbit(x) (x&-x)
#define read(x) x=getint()
#define rep(i, n) for(int i=0; i<n; ++i)
#define for1(i, a, n) for(int i=a; i<=(n); ++i)
#define MID (l+r)>>1
inline const int getint() { char c=getchar(); int k=1, r=0; for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
const int N=10005;
struct ND { int l, r, s; } t[N*200];
int tot, n, m, a[N], root[N], R[N], L[N], ans[N+N], cl, cr, cnt, QL[N], QR[N], K[N], num;
bool ask[N];
void update(const int &l, const int &r, int &pos, const int &key, const int &siz) {
t[++tot]=t[pos]; t[tot].s+=siz; pos=tot;
if(l==r) return;
int m=MID;
if(key<=m) update(l, m, t[pos].l, key, siz); else update(m+1, r, t[pos].r, key, siz);
}
inline void change(int x, const int &key, const int &siz) { for(; x<=n; x+=lowbit(x)) update(1, num, root[x], key, siz); }
int query(const int &l, const int &r, const int &k) {
if(l==r) return l;
int suml=0, sumr=0;
for1(i, 1, cl) suml+=t[t[L[i]].l].s;
for1(i, 1, cr) sumr+=t[t[R[i]].l].s;
int s=sumr-suml, m=MID;
if(k<=s) {
for1(i, 1, cl) L[i]=t[L[i]].l;
for1(i, 1, cr) R[i]=t[R[i]].l;
return query(l, m, k);
}
else {
for1(i, 1, cl) L[i]=t[L[i]].r;
for1(i, 1, cr) R[i]=t[R[i]].r;
return query(m+1, r, k-s);
}
}
inline int getans(int l, int r, const int &k) {
for(cl=0; l>0; l-=lowbit(l)) L[++cl]=root[l];
for(cr=0; r>0; r-=lowbit(r)) R[++cr]=root[r];
return query(1, num, k);
}
int main() {
read(n); read(m); char c;
for1(i, 1, n) read(a[i]), ans[++cnt]=a[i];
for1(i, 1, m) {
for(c=getchar(); c<'A'||c>'Z'; c=getchar());
read(QL[i]); read(QR[i]);
if(c=='Q') read(K[i]), ask[i]=1;
else ans[++cnt]=QR[i];
}
sort(ans+1, ans+1+cnt); //咱们先离散,在这里用不着再开个域id了
ans[cnt+1]=1000000013;
for1(i, 1, cnt) if(ans[i]!=ans[i+1]) ans[++num]=ans[i]; //将重复的累起来,缩小主席树的区间
for1(i, 1, n) a[i]=lower_bound(ans+1, ans+1+num, a[i])-ans; //查找原来数据在新数据的位置,这里可以直接覆盖了
for1(i, 1, n) change(i, a[i], 1);
for1(i, 1, m) {
if(ask[i]) printf("%d\n", ans[getans(QL[i]-1, QR[i], K[i])]);
else {
change(QL[i], a[QL[i]], -1); //先将原来的剪掉
a[QL[i]]=lower_bound(ans+1, ans+1+num, QR[i])-ans; //改变位置
change(QL[i], a[QL[i]], 1); //再将新的加上
}
} return 0;
}

Description

给定一个含有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-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序, 从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。 第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。分别表示序列的长度和指令的个数。第二行有n个数,表示 a[1],a[2]……a[n],这些数都小于10^9。接下来的m行描述每条指令,每行的格式是下面两种格式中的一种。 Q i j k 或者 C i t Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。

Input

对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

Output

Sample Input

5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3

Sample Output

3
6

HINT

20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。

Source

【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)的更多相关文章

  1. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

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

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

  3. P2617 Dynamic Rankings(树状数组套主席树)

    P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...

  4. LUOGU P2617 Dynamic Rankings(树状数组套主席树)

    传送门 解题思路 动态区间第\(k\)大,树状数组套主席树模板.树状数组的每个位置的意思的是每棵主席树的根,维护的是一个前缀和.然后询问的时候\(log\)个点一起做前缀和,一起移动.时空复杂度\(O ...

  5. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  6. BZOJ 2141 排队(树状数组套主席树)

    解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...

  7. BZOJ.1901.Dynamic Rankings(树状数组套主席树(动态主席树))

    题目链接 BZOJ 洛谷 区间第k小,我们可以想到主席树.然而这是静态的,怎么支持修改? 静态的主席树是利用前缀和+差分来求解的,那么对于每个位置上的每棵树看做一个点,拿树状数组更新. 还是树状数组的 ...

  8. BZOJ1901 - Dynamic Rankings(树状数组套主席树)

    题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t  要求你把第i个数修改为t 题解 动态的区间第k ...

  9. BZOJ 1901: Zju2112 Dynamic Rankings 区间k大 带修改 在线 线段树套平衡树

    之前写线段树套splay数组版..写了6.2k..然后弃疗了.现在发现还是很水的..嘎嘎.. zju过不了,超时. upd:才发现zju是多组数据..TLE一版才发现.然后改了,MLE...手写内存池 ...

随机推荐

  1. HDOj 1010 DFS优化

    #include<cstdio> #include<cstring> ]={,,,-}; ]={,,-,}; ][]; int x1,y1,x2,y2; int step; i ...

  2. django-cms 代码研究(六)plugin的深入分析

    示例代码: https://github.com/divio/djangocms-picture 以上一个图片的插件,安装后可在页面中添加图片,效果如下图: 以此为切入点,分析plugin的逻辑: 分 ...

  3. users

    NAME users - print the user names of users currently logged in to the current host SYNOPSIS users [O ...

  4. Ubuntu删除history记录

    history -c就是清除本次登录到目前所执行的命令 转自: http://www.linuxdiyf.com/viewarticle.php?id=189355

  5. 【SpringMVC】SpringMVC系列9之Model数据返回到View

    9.Model数据返回到View 9.1.概述     Spring MVC 提供了以下几种途径输出模型数据: ModelAndView: 处理方法返回值类型为 ModelAndView 时, 方法体 ...

  6. cocos2d-x 制作系统公告

    2013-12-15 21:57:33 下载地址:http://download.csdn.net/detail/jackyvincefu/6434549 (摘自:CSDN资源) CTestLayer ...

  7. iOS 推荐学习__bridge等ARC知识的好资料

    请下载 iOS5 by Tutorials!写得很好的!

  8. Java for LeetCode 152 Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  9. JDK1.7 ConcurrentHashMap 源码浅析

    概述 ConcurrentHashMap是HashMap的线程安全版本,使用了分段加锁的方案,在高并发时有比较好的性能. 本文分析JDK1.7中ConcurrentHashMap的实现. 正文 Con ...

  10. Android之XML序列化和解析

    XML文件是一种常用的文件格式,可以用来存储与传递数据 ,本文是XML文件序列化与解析的一个简单示例 写文件到本地,并用XML格式存储 /** * 写xml文件到本地 */ private void ...