caioj1442:第k小的数Ⅱ
【传送门:caioj1442】
简要题意:
给出n个点,每个点都有一个权值,m个操作,操作有两种:第一种是询问l到r的第k小的值,然后输出这个值,第二种是将第x个点的值改为k
题解:
又是一道主席树的例题,不过简直比前两题(caioj1441,caioj1443)难不止一点点
看到第一种操作,我们可以用主席树来搞,但是第二种操作的话,我们就要用树状数组来维护每个第二种操作所带来的影响,而且每次要求第一种操作的时候都要先在树状数组中找到相应的点,然后再处理主席树
参考代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
int a[];
struct node
{
int lc,rc,c;
}tr[];int cnt;
int rt[];int n;
int ust[];//树状数组
int lowbit(int x)//树状数组用来找上司或下属
{
return x&-x;
}
void Link(int &u,int l,int r,int p,int c)
{
if(u==) u=++cnt;
tr[u].c+=c;
if(l==r) return ;
int mid=(l+r)/;
if(p<=mid) Link(tr[u].lc,l,mid,p,c);
else Link(tr[u].rc,mid+,r,p,c);
}
void Merge(int &u1,int u2)
{
if(u1==){u1=u2;return ;}
if(u2==) return ;
tr[u1].c+=tr[u2].c;
Merge(tr[u1].lc,tr[u2].lc);
Merge(tr[u1].rc,tr[u2].rc);
}
void Turn(int u,int c)//树状数组的实时更新
//c==-1时树状数组记录每个点所在线段树的根
//c==0时记录左孩子
//c==1时记录右孩子
{
while(u>=n+)
{
if(c==-) ust[u]=rt[u];
else if(c==) ust[u]=tr[ust[u]].lc;
else if(c==) ust[u]=tr[ust[u]].rc;
u-=lowbit(u);
}
}
void Modefy(int u,int p,int c)//对于修改值就用树状数组来节约时间
{
while(u<=*n)
{
Link(rt[u],,,p,c);
u+=lowbit(u);
}
}
int Getsum(int u)//求出修改过后树状数组得到的值
{
int ret=;
while(u>=n+)
{
ret+=tr[tr[ust[u]].lc].c;
u-=lowbit(u);
}
return ret;
}
int Ask(int u1,int u2,int p1,int p2,int l,int r,int p)
{
if(l==r) return l;
int c=tr[tr[u2].lc].c-tr[tr[u1].lc].c+Getsum(p2+n)-Getsum(p1+n);
int mid=(l+r)/;
if(p<=c)
{
Turn(p1+n,);
Turn(p2+n,);
return Ask(tr[u1].lc,tr[u2].lc,p1,p2,l,mid,p);
}
else
{
Turn(p1+n,);
Turn(p2+n,);
return Ask(tr[u1].rc,tr[u2].rc,p1,p2,mid+,r,p-c);
}
}
int main()
{
int m;
scanf("%d%d",&n,&m);
cnt=;memset(rt,,sizeof(rt));
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
Link(rt[i],,,a[i],);
Merge(rt[i],rt[i-]);
}
char st[];
for(int i=;i<=m;i++)
{
scanf("%s",st+);
if(st[]=='Q')
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
Turn(l+n-,-);
Turn(r+n,-);
printf("%d\n",Ask(rt[l-],rt[r],l-,r,,,k));
}
else
{
int p,c;
scanf("%d%d",&p,&c);
Modefy(p+n,a[p],-);
a[p]=c;
Modefy(p+n,a[p],);
}
}
return ;
}
caioj1442:第k小的数Ⅱ的更多相关文章
- *HDU2852 树状数组(求第K小的数)
KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- 计算序列中第k小的数
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4046399.html 使用分治算法,首先选择随机选择轴值pivot,并使的序列中比pivot ...
- [LeetCode] Find K-th Smallest Pair Distance 找第K小的数对儿距离
Given an integer array, return the k-th smallest distance among all the pairs. The distance of a pai ...
- #7 找出数组中第k小的数
「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...
- 无序数组求第k大/第k小的数
根据http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html 博客中所总结的7种解法,我挑了其中的解法3和解法6进行了实现. 解法3: ...
- 查找第K小的数 BFPRT算法
出处 http://blog.csdn.net/adong76/article/details/10071297 BFPRT算法是解决从n个数中选择第k大或第k小的数这个经典问题的著名算法,但很多人并 ...
- 基于快速排序思想partition查找第K大的数或者第K小的数。
快速排序 下面是之前实现过的快速排序的代码. function quickSort(a,left,right){ if(left==right)return; let key=partition(a, ...
- 算法---数组总结篇2——找丢失的数,找最大最小,前k大,第k小的数
一.如何找出数组中丢失的数 题目描述:给定一个由n-1个整数组成的未排序的数组序列,其原始都是1到n中的不同的整数,请写出一个寻找数组序列中缺失整数的线性时间算法 方法1:累加求和 时间复杂度是O(N ...
- cogs930找第k小的数(k-th number)
cogs930找第k小的数(k-th number) 原题链接 题解 好题... 终极版是bzoj3065(然而并不会) 先讲这个题... 维护\(n+1\)个值域线段树(用主席树),标号\(0\) ...
随机推荐
- JavaScript设计模式(biaoyansu)(2)
单例模式实例 (创建类模式): let elBalance = document.getElementById('balance') function init () { var a = new Di ...
- [NOIP2012提高组]疫情控制
题目:洛谷P1084.codevs1218.Vijos P1783. 题目大意:有一棵n个节点的,根为1的带权树和m支军队.每支军队可以在一个点上停下,那么从1开始就不能经过这个点了.现在有m支军队已 ...
- fastJson 解析
String object = JSON.toJSONString(obj); ------------------obj必须序列化 JSONObject jso=JSON ...
- 阿里云部署java项目
第一步:注册阿里云账号(如果有请看第二步) 1.百度搜索阿里云,点击进入阿里云官网 2.点击右上角免费注册 3.进入注册页面,按照要求填写信息 4.注册完成后登陆 登陆之后首先购买阿里云esc与服务器 ...
- 紫书 例题11-4 UVa247 (Floyd判断联通)
Floyd联通, 然后为了输出联通分量而新建一个图, 让互相可以打电话的建立一条边, 然后dfs输出联通分量就ok了. #include<cstdio> #include<iostr ...
- Lucene3.6.2包介绍,第一个Lucene案例介绍,查看索引信息的工具lukeall介绍,Luke查看的索引库内容,索引查找过程
2.Lucene3.6.2包介绍,第一个Lucene案例介绍,查看索引信息的工具lukeall介绍,Luke查看的索引库内容,索引查找过程 2014-12-07 23:39 2623人阅读 评论(0) ...
- Web长连接推送
http://www.workerman.net/web-sender http://wahahachuang5.iteye.com/blog/2311313
- [PYTHON]一个简单的单元測试框架
近期尝试了一下TDD(測试驱动)的模式.感觉效果不错.在此总结一下,同学们假设有更好的办法,一定要告诉我:) 1. 每一个功能模块(文件),配一个单元測试模块. 以手头这个项目为样例:有LogCat. ...
- linux安装oracleclient
1.准备好所须要的安装包,http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html这个网 ...
- Compile OpenCASCADE7.3 with VS2008
Compile OpenCASCADE7.3 with VS2008 eryar@163.com 概述 在OpenCASCADE的源码文件夹中有个adm文件夹,里面提供了各个平台中编译源码的项目文件. ...