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

 输出文件应包含T行。对于每一组数据,如果该关卡有解,输出一行Yes;否则输出一行No。

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。

【分析】

裸的主席树,直接上模板就行了。

 /**************************************************************
Problem: 1901
User: TCtower
Language: C++
Result: Accepted
Time:612 ms
Memory:24988 kb
****************************************************************/ #include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
//#define LOCAL
const int maxn=+;
const int INF=;
const int maxnode=+;
using namespace std;
struct OP
{
int type;//0代表询问,1代表改变
int l,r,k;
}op[maxn];
//点结构体
struct node
{
int ls,rs,w;
node(){ls=rs=w=;}
}T[maxnode];
vector<int>LX;
vector<int>Q1,Q2;
int a[maxn],n,q,n1;
int cnt,root[maxn*]; void init();
void work();
//树状数组用
inline int lowbit(int i){return i&-i;}
inline int find(int i)
{
//二分查找不解释
return (lower_bound(LX.begin(),LX.begin()+n1,i)-LX.begin())+;
}
void build(int &i,int l,int r,int val);
void query(int l,int r,int k);//区间第k大
//其实我觉得不传副本速度会上升?
int Qy(vector<int>Q1,vector<int>Q2,int l,int r,int k);
void my_ins(int pos,int x,int v);
void ins(int &i,int l,int r,int x,int v); int main()
{
#ifdef LOCAL
freopen("data.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
init();//读入与初始化
work();
return ;
}
void init()
{
scanf("%d%d",&n,&q);
LX.clear();
for (int i=;i<=n;i++)
{
scanf("%d",&a[i]);
LX.push_back(a[i]);
}
char str[];
for (int i=;i<=q;i++)
{
scanf("%s",str);
if (str[]=='Q')
{
op[i].type=;
scanf("%d%d%d",&op[i].l,&op[i].r,&op[i].k);
}
else
{
op[i].type=;
scanf("%d%d",&op[i].l,&op[i].r);
LX.push_back(op[i].r);
}
}
sort(LX.begin(),LX.end());
n1=unique(LX.begin(),LX.end())-LX.begin();
}
void ins(int &i,int l,int r,int x,int v)
{
if (i==) {T[++cnt]=T[i];i=cnt;}//没有创建过新的节点
T[i].w+=v;
if (l==r) return;
int mid=(l+r)>>;
if (x<=mid) ins(T[i].ls,l,mid,x,v);
else ins(T[i].rs,mid+,r,x,v);
}
void my_ins(int pos,int x,int v)
{
int t=find(x);//找到x的位置
for (int i=pos;i<=n;i+=lowbit(i))
{
ins(root[i],,n1,t,v);
}
}
int Qy(vector<int>Q1,vector<int>Q2,int l,int r,int k)
{
if (l==r) return l;
int c=,mid=(l+r)>>;
//这两句可以互换,统计总数
for (int i=;i<Q1.size();i++) c-=T[T[Q1[i]].ls].w;
for (int i=;i<Q2.size();i++) c+=T[T[Q2[i]].ls].w;
//大于k说明在左子树中而不右子树
for (int i=;i<Q1.size();i++) Q1[i]=(c>=k?T[Q1[i]].ls:T[Q1[i]].rs);
for (int i=;i<Q2.size();i++) Q2[i]=(c>=k?T[Q2[i]].ls:T[Q2[i]].rs);
if (c>=k) return Qy(Q1,Q2,l,mid,k);//继续向下寻找
else return Qy(Q1,Q2,mid+,r,k-c);
}
void query(int l,int r,int k)
{
Q1.clear();Q2.clear();//临时队列清空
Q1.push_back(root[l!=?l-+n:]);
Q2.push_back(root[r+n]);
for (int i=l-;i;i-=lowbit(i)) Q1.push_back(root[i]);
for (int i=r;i;i-=lowbit(i)) Q2.push_back(root[i]);
int t=Qy(Q1,Q2,,n1,k);
printf("%d\n",LX[t-]);
}
void work()
{
cnt=;
memset(root,,sizeof(root));
for (int i=;i<=n;i++)
{
root[i+n]=root[i+n-];
int t=find(a[i]);
build(root[i+n],,n1,t);
}
for (int i=;i<=q;i++)
{
if (op[i].type==)
query(op[i].l,op[i].r,op[i].k);
else
{
my_ins(op[i].l,a[op[i].l],-);
my_ins(op[i].l,op[i].r,);
//修改
a[op[i].l]=op[i].r;
}
}
}
void build(int &i,int l,int r,int val)
{
//对于修改过的每一个点
//都要新建一个副本
T[++cnt]=T[i];i=cnt;
T[i].w++;
if (l==r) return;
int mid=(l+r)>>;
//按值建线段树
if (val<=mid) build(T[i].ls,l,mid,val);
else build(T[i].rs,mid+,r,val);
}

【BZOJ1901】Dynamic Rankings的更多相关文章

  1. 【BZOJ-1901】Dynamic Rankings 带修主席树

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

  2. 【BZOJ1901】Dynamic Rankings [整体二分]

    Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 给定一个含 ...

  3. 【BZOJ1901】Dynamic Rankings(树套树,树状数组,主席树)

    题意:给定一个N个数的序列,要求维护一个数据结构支持以下两种操作: 1:将第X个数改成Y 2:查询第X到第Y个数里第K小的数是多少 n,m<=10000,a[i]<=10^9 思路:单点修 ...

  4. 【BZOJ】【1901】【Zju2112】 Dynamic Rankings

    再填个坑. 动态维护区间第K大(带单点修改) 首先裸的区间第K大我们是用的[前缀和]思想,实现O(n)预处理,O(1)找树查询,那么如果是动态的呢?我们可以利用树状数组(BIT)的思想,进行O(log ...

  5. 【bzoj1901】dynamic ranking(带修改主席树/树套树)

    题面地址(权限题) 不用权限题的地址 首先说说怎么搞带修改主席树? 回忆一般的kth问题,我们的主席树求的是前缀和,这样我们在目标区间的左右端点的主席树差分下就能求出kth. 那么我们如何支持修改操作 ...

  6. 【bzoj1901】dynamic ranking(带修改主席树)

    传送门(权限) 传送门(非权限) 花了一晚上总算把代码调好了……才知道待修改主席树怎么操作…… 然而还是一知半解orz…… 先说说我的理解吧 我们一般建主席树的时候都是直接在序列上建的 但是如果有修改 ...

  7. 【BZOJ1901】Zju2112 Dynamic Rankings 主席树+树状数组

    [BZOJ1901]Zju2112 Dynamic Rankings Description 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j ...

  8. 【BZOJ1901】【Luogu2617】Dynamic Ranking(主席树,树状数组)

    [BZOJ1901][Luogu2617]Dynamic Ranking(主席树,树状数组) 题面 神TM BZOJ权限题 Luogu真良心 题解 如果不考虑修改 很容易的主席树区间第K大 考虑修改 ...

  9. [BZOJ1901]Zju2112 Dynamic Rankings

    [BZOJ1901]Zju2112 Dynamic Rankings 试题描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i ...

随机推荐

  1. 【HDOJ】2428 Stars

    先排序后二分. #include <iostream> #include <cstdio> #include <cstring> #include <algo ...

  2. 怒刷BZOJ记录(一)1001~1037

    我实在是太弱了...不滚粗只能刷BZOJ了...这里来记录每天刷了什么题吧. 2015-7-9 : 1001[BeiJing2006]狼抓兔子                 | 最大流练习(呃..其 ...

  3. 图论(差分约束系统):POJ 1275 Cashier Employment

    Cashier Employment Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7651   Accepted: 288 ...

  4. 【模拟】NEERC15 E Easy Problemset (2015-2016 ACM-ICPC)(Codeforces GYM 100851)

    题目链接: http://codeforces.com/gym/100851 题目大意: N个人,每个人有pi个物品,每个物品价值为0~49.每次从1~n顺序选当前这个人的物品,如果这个物品的价值&g ...

  5. div+css模式编写html静态网页例子_仿照网页制作

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 滑雪 (搜索)(dp)(贪心)

    以每一点为起点找出所有路径,并求出以此点做为起点的最大路径 求出每个点的最大路径后再找出其中最大的值,输出最大值 #include <stdio.h>#include <string ...

  7. makeKeyAndVisible的作用

    [self.window makeKeyAndVisible]; 这个是便捷方法,去使被使用对象的主窗口显示到屏幕的最前端.你也可以使用hiddenUIView方法隐藏这个窗口

  8. android设置view透明度的效果

    android设置view透明度的效果 推荐textView.setBackgroundColor(Color.TRANSPARENT);     第一种方法:在xml文件中设置背景颜色. andro ...

  9. 《火球——UML大战需求分析》(第1章 大话UML)——1.2 结构型的UML(Structure Diagram)

    说明: <火球——UML大战需求分析>是我撰写的一本关于需求分析及UML方面的书,我将会在CSDN上为大家分享前面几章的内容,总字数在几万以上,图片有数十张.欢迎你按文章的序号顺序阅读,谢 ...

  10. bitbucket/github同一站点上多个git代码仓库的ssh-key配置

    由于项目开发需要,可能多个项目都放在bitbucket或者github上面,每个项目都有独立的sshkey,这就会造成push时的系统默认取~/.ssh/id_rsa的问题. 最简单的解决方法是这样: ...