题目链接:BZOJ - 1901

题目分析

树状数组套线段树或线段树套线段树都可以解决这道题。

第一层是区间,第二层是权值。

空间复杂度和时间复杂度均为 O(n log^2 n)。

线段树比树状数组麻烦好多...我容易写错= =

代码

树状数组套线段树

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring> using namespace std; const int MaxN = 10000 + 5, MN = 1000000015, MaxNode = 10000 * 30 * 15 + 15; int n, m, Index, Used_Index;
int A[MaxN], Root[MaxN], Son[MaxNode][2], T[MaxNode], U[MaxN], C[MaxN]; void Add(int &x, int s, int t, int Pos, int Num)
{
if (x == 0) x = ++Index;
T[x] += Num;
if (s == t) return;
int m = (s + t) >> 1;
if (Pos <= m) Add(Son[x][0], s, m, Pos, Num);
else Add(Son[x][1], m + 1, t, Pos, Num);
} void Change(int x, int Pos, int Num)
{
for (int i = x; i <= n; i += i & -i)
Add(Root[i], 0, MN, Pos, Num);
} int Get_Sum(int x)
{
int ret = 0;
for (int i = x; i; i -= i & -i)
ret += T[Son[U[i]][0]];
return ret;
} void Init_U(int x)
{
for (int i = x; i; i -= i & -i)
U[i] = Root[i];
} void Turn(int x, int f)
{
for (int i = x; i; i -= i & -i)
{
if (C[i] == Used_Index) break;
C[i] = Used_Index;
U[i] = Son[U[i]][f];
}
} int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
{
scanf("%d", &A[i]);
Change(i, A[i], 1);
}
char f;
int Pos, Num, L, R, k, Temp;
for (int i = 1; i <= m; ++i)
{
f = '-';
while (f < 'A' || f > 'Z') f = getchar();
if (f == 'C')
{
scanf("%d%d", &Pos, &Num);
Change(Pos, A[Pos], -1);
A[Pos] = Num;
Change(Pos, Num, 1);
}
else
{
scanf("%d%d%d", &L, &R, &k);
int l, r, mid;
l = 0; r = MN;
Init_U(L - 1);
Init_U(R);
Used_Index = 0;
while (l < r)
{
mid = (l + r) >> 1;
Temp = Get_Sum(R) - Get_Sum(L - 1);
++Used_Index;
if (Temp >= k)
{
r = mid;
Turn(L - 1, 0);
Turn(R, 0);
}
else
{
l = mid + 1;
k -= Temp;
Turn(L - 1, 1);
Turn(R, 1);
}
}
printf("%d\n", l);
}
}
return 0;
}

线段树套线段树

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; const int MaxN = 10000 + 5, MN = 1000000000 + 15, MaxNode = 10000 * 30 * 15 + 15; int n, m, Index, Used_Index;
int A[MaxN], Root[MaxN * 4], T[MaxNode], Son[MaxNode][2], U[MaxN * 4], C[MaxN * 4]; void Add(int &x, int s, int t, int Pos, int Num)
{
if (x == 0) x = ++Index;
T[x] += Num;
if (s == t) return;
int m = (s + t) >> 1;
if (Pos <= m) Add(Son[x][0], s, m, Pos, Num);
else Add(Son[x][1], m + 1, t, Pos, Num);
} void Change(int x, int s, int t, int Pos, int Pos_2, int Num)
{
Add(Root[x], 0, MN, Pos_2, Num);
if (s == t) return;
int m = (s + t) >> 1;
if (Pos <= m) Change(x << 1, s, m, Pos, Pos_2, Num);
else Change(x << 1 | 1, m + 1, t, Pos, Pos_2, Num);
} void Init_U(int x, int s, int t, int Pos)
{
if (Pos >= t)
{
U[x] = Root[x];
return;
}
int m = (s + t) >> 1;
Init_U(x << 1, s, m, Pos);
if (Pos >= m + 1) Init_U(x << 1 | 1, m + 1, t, Pos);
} void Turn(int x, int s, int t, int Pos, int f)
{
if (Pos >= t)
{
if (C[x] == Used_Index) return;
C[x] = Used_Index;
U[x] = Son[U[x]][f];
return;
}
int m = (s + t) >> 1;
Turn(x << 1, s, m, Pos, f);
if (Pos >= m + 1) Turn(x << 1 | 1, m + 1, t, Pos, f);
} int Get_Sum(int x, int s, int t, int Pos)
{
if (Pos >= t) return T[Son[U[x]][0]];
int ret = 0, m = (s + t) >> 1;
ret += Get_Sum(x << 1, s, m, Pos);
if (Pos >= m + 1) ret += Get_Sum(x << 1 | 1, m + 1, t, Pos);
return ret;
} int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
{
scanf("%d", &A[i]);
Change(1, 0, n, i, A[i], 1);
}
char f;
int L, R, Pos, Num, k;
for (int i = 1; i <= m; ++i)
{
f = '-';
while (f < 'A' || f > 'Z') f = getchar();
if (f == 'C')
{
scanf("%d%d", &Pos, &Num);
Change(1, 0, n, Pos, A[Pos], -1);
A[Pos] = Num;
Change(1, 0, n, Pos, Num, 1);
}
else
{
scanf("%d%d%d", &L, &R, &k);
int l, r, mid, Temp;
Used_Index = 0;
Init_U(1, 0, n, L - 1);
Init_U(1, 0, n, R);
l = 0; r = MN;
while (l < r)
{
++Used_Index;
mid = (l + r) >> 1;
Temp = Get_Sum(1, 0, n, R) - Get_Sum(1, 0, n, L - 1);
if (Temp >= k)
{
r = mid;
Turn(1, 0, n, R, 0);
Turn(1, 0, n, L - 1, 0);
}
else
{
l = mid + 1;
Turn(1, 0, n, R, 1);
Turn(1, 0, n, L - 1, 1);
k -= Temp;
}
}
printf("%d\n", l);
}
}
return 0;
}

  

[BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】的更多相关文章

  1. bzoj 1901 Dynamic Rankings (树状数组套线段树)

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1] ...

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

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

  3. BZOJ 1901 Dynamic Rankings (整体二分+树状数组)

    题目大意:略 洛谷传送门 这道题在洛谷上数据比较强 貌似这个题比较常见的写法是树状数组套主席树,动态修改 我写的是整体二分 一开始的序列全都视为插入 对于修改操作,把它拆分成插入和删除两个操作 像$C ...

  4. BZOJ.1901.Dynamic Rankings(线段树套平衡树 Splay)

    题目链接or Here 题意:n个数,有两个操作:1.修改某个数为v:2.询问一段区间第k小的数 如果没有修改,则可以用线段树,每个节点P[a,b]存储大小为b-a+1的数组,代表其中的数 同时,这个 ...

  5. BZOJ 1901 Dynamic Rankings 树董事长

    标题效果:间隔可以改变k少 我的两个天树牌主席... 隔断Count On A Tree 之后我一直认为,随着树的主席的变化是分域林木覆盖率可持久段树. .. 事实上,我是误导... 尼可持久化线段树 ...

  6. [BZOJ 1901] Dynamic Rankings

    Link: BZOJ 1901 传送门 Solution: 带修改主席树的模板题 对于静态区间第$k$大直接上主席树就行了 但加上修改后会发现修改时复杂度不满足要求了: 去掉/增加第$i$位上的值时要 ...

  7. BZOJ.1901.Dynamic Rankings(整体二分)

    题目链接 BZOJ 洛谷 (以下是口胡) 对于多组的询问.修改,我们可以发现: 假设有对p1,p2,p3...的询问,在这之前有对p0的修改(比如+1),且p0<=p1,p2,p3...,那么我 ...

  8. 【BZOJ 1901】Zju2112 Dynamic Rankings &&【COGS 257】动态排名系统 树状数组套线段树

    外面是树状数组,里面是动态开点线段树,对于查询我们先把有关点找出来,然后一起在线段树上行走,这样就是单个O(log2)的了 #include <cstdio> #include <v ...

  9. Bzoj 1901: Zju2112 Dynamic Rankings 主席树,可持久,树状数组,离散化

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6321  Solved: 2628[Su ...

随机推荐

  1. tabhost中setup()和setup(LocalActivityManager activityGroup)

    如果用系统默认的tabhost时, 直接用getTabhost()初始化,整个类继承tabActivity. 当没有选择系统tabhost默认id时,而是自己定义的id时,必须使用 findViewB ...

  2. 用NodeJs实现延迟调用,规避定时任务的闭包问题

    很多人在用NodeJs的setTimeout(callback, delay[, arg][, ...])编写定时任务时,习惯上直接操作callback外部的对象object(闭包的特点).这样做有一 ...

  3. linux中的帮助命令 分类: linux 学习笔记 ubuntu 2015-07-05 19:07 31人阅读 评论(0) 收藏

    说实话,到目前为止我还是不太习惯使用linux自带的帮助文档,遇到问题都是去查我自己下载的chm格式的命令大全,不过这些帮助命令我们还是有必要了解的. 1.man [要查看的命令名称] 例如想要查看l ...

  4. 11.10 noip模拟试题

    1.第K小数 (number.cpp/c/pas) [问题描述] 有两个正整数数列,元素个数分别为N和M.从两个数列中分别任取一个数 相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少 ...

  5. javascript创建对象的7种方式

    /*1.工厂模式*/ function createPerson(name,age,job) { var o = new object(); o.name = name; o.age = age; o ...

  6. Android客户端中Bitmap的下载过程和缓存机制

    加载流程: if(内存命中){      从内存中读取 }else{      create AsyncTasks,task中的多个Runnable是通过堆栈先进后出的方式来调度,而非队列式的先进先出 ...

  7. Handler 原理分析和使用(一)

    我为什么写Handler,原因主要还在于它在整个 Android 应用层面非常之关键,他是线程间相互通信的主要手段.最为常用的是其他线程通过Handler向主线程发送消息,更新主线程UI. 下面是一个 ...

  8. Cisco AnyConnect “Failed to initialize connection subsystem”的解决方案

    Per Cisco: Microsoft has released a fix-it patch providing a workaround for this issue. See KB# 3023 ...

  9. SQL2008安装提示"Microsoft visual studio 2008早期之前的版本"解决(这是我认为最简单有效的方法)

    作者:冰封 日期:2013-10-18 原文地址:http://www.skywj.com/thread-9230-1-1.html 在安装SQL Server的时候提示 Microsoft visu ...

  10. OC - 14.NSOperation与NSOperationQueue

    简介 通过NSOperation与NSOperationQueue的组合也能实现多线程 通常将任务封装成NSOperation对象,并将对象添加到NSOperationQueue中实现 NSOpera ...