1、题目大意:区间第k小,有单点修改

2、分析:这个是树状数组套线段树,也是主席树。。。。为什么主席树这么多QAQ

就是树套树的那种插入什么的,注意啊,一定要动态开内存。。不然会爆。。

然后算答案有两种算法,一种是二分答案,然后算一下,另一种就是把logn棵线段树的指针都存一下,

然后再递归找第k大的时候,我们就可以暴力枚举这些指针,别忘了维护他们

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
struct segment{
    segment *ls, *rs;
    int num;
} *root[10010], ft[11000010];
int cnt;
int a[10010];
int n, m;
inline void tree_insert(segment* &p, int l, int r, int value){
    if(p == NULL) p = &ft[cnt ++];
    if(l == r){
        p -> num ++;
        return;
    }
    int mid = (l + r) / 2;
    if(value <= mid) tree_insert(p -> ls, l, mid, value);
    else tree_insert(p -> rs, mid + 1, r, value);
    p -> num = 0;
    if(p -> ls) p -> num += p -> ls -> num;
    if(p -> rs) p -> num += p -> rs -> num;
}
inline void tree_Delete(segment* &p, int l, int r, int value){
    if(p == NULL) p = &ft[cnt ++];
    if(l == r){
        p -> num --;
        return;
    }
    int mid = (l + r) / 2;
    if(value <= mid) tree_Delete(p -> ls, l, mid, value);
    else tree_Delete(p -> rs, mid + 1, r, value);
    p -> num = 0;
    if(p -> ls) p -> num += p -> ls -> num;
    if(p -> rs) p -> num += p -> rs -> num;
}
inline int tree_lessk(segment* &p, int l, int r, int value){
    if(!p) return 0;
    if(l == r) return p -> num;
    int mid = (l + r) / 2;
    int ret = 0;
    if(value <= mid) ret += tree_lessk(p -> ls, l, mid, value);
    else {
        if(p -> ls) ret += p -> ls -> num;
        ret += tree_lessk(p -> rs, mid + 1, r, value);
    }
    return ret;
}
inline void insert(int x, int y){
    for(; x <= n; x += (x & -x))
        tree_insert(root[x], 0, 1000000000, y);
}
inline void Delete(int x, int y){
    for(; x <= n; x += (x & -x))
        tree_Delete(root[x], 0, 1000000000, y);
}
inline int lessk(int x, int y){
    int ret = 0;
    for(; x > 0; x -= (x & -x))
        ret += tree_lessk(root[x], 0, 1000000000, y);
    return ret;
}
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++){
        scanf("%d", &a[i]);
        insert(i, a[i]);
    }
    char str[2];
    int x, y, z;
    for(int i = 1; i <= m; i ++){
        scanf("%s", str);
        scanf("%d%d", &x, &y);
        if(str[0] == 'Q'){
            scanf("%d", &z);
            int l = 0, r = 1000000000;
            while(l < r){
                int mid = (l + r) / 2;
                if(lessk(y, mid) - lessk(x - 1, mid) >= z) r = mid;
                else l = mid + 1;
            }
            printf("%d\n", l);
        }
        else{
            Delete(x, a[x]);
            a[x] = y;
            insert(x, a[x]);
        }
    }
    return 0;
} 

最新文章

  1. 《javascript权威指南》读书笔记——第二篇
  2. 【转】段错误调试神器 - Core Dump详解
  3. 打造一个有感觉的vim(四)
  4. 素数筛 uva 543
  5. php大力力 [010节]PHP常量
  6. Linux启动过程详解 (转)
  7. adb 工具学习
  8. Hibernate映射类型对照表
  9. 深入了解overflow
  10. 【模拟】FOJ 2244 Daxia want to buy house
  11. 主流H.264编码器对比测试 (MSU出品)
  12. PHP后台传值
  13. WebStorm 使用快捷键大全
  14. SQL注入(一)普通型注入
  15. yali项目的slider
  16. UISearchBar的扩展使用
  17. Ajax.Nodejs.跨域访问
  18. jackson 流式API
  19. BalkanOI 2018 Parentrises(贪心+基础DP)
  20. Spring Boot IoC 容器初始化过程

热门文章

  1. C#开发和调用Web Service
  2. js 连接地址分析
  3. ecshop 影响全局的标量lib_main.php
  4. yourphp超出20记录自动删除
  5. Intent启动一个新的页面
  6. ERROR 2002 (HY000): Can&#39;t connect to local MySQL server through socket &#39;/var/lib/mysql/mysql.sock&#39; (2)--MySQL错误
  7. YII2数据库依赖缓存
  8. Yii2 数据操作Query Builder(转)
  9. Mono资源
  10. 【转载】 C中的access函数