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\) ...
随机推荐
- redis中的事务、lua脚本和管道的使用场景
参考文章 : https://blog.csdn.net/fangjian1204/article/details/50585080
- pace.js 原理(转)
pace.js监控了什么: pace.js对于加载进度监控了什么呢?通过阅读源码,我们看到整体的进度有四个部分组成:document,elements,eventLag和ajax这四种监视器(Moni ...
- NOIp2018模拟赛三十五
两道大数据结构把我砸懵 成绩:未提交 Orz xfz两道正解 A:[BZOJ4049][CREC2014B]mountainous landscape B:CJB的大作(CF改编题)
- luogu P4139 上帝与集合的正确用法(扩展欧拉定理)
本蒟蒻现在才知带扩展欧拉定理. 对于任意的\(b\geq\varphi(p)\)有 \(a^b\equiv a^{b\ mod\ \varphi(p)+\varphi(p)}(mod\ p)\) 当\ ...
- 紫书 例题 10-3 UVa 10375 (唯一分解定理)
这道题感觉非常的秀 因为结果会很大,所以就质因数分解分开来算 非常的巧妙! #include<cstdio> #include<vector> #include<cstr ...
- POJ——T2446 Chessboard
http://poj.org/problem?id=2446 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18560 ...
- 【Linux编程】socket编程
套接字是通信端点的抽象.文件描写叙述符用open函数创建,而套接字描写叙述符用socket函数创建.socket函数原型例如以下: int socket(int domain, int type, i ...
- cocos2dx 几个精灵依照顺序播放动画解决方法
我先描写叙述一下这个问题: 拿之前做的卡牌游戏来说.假设一方场上有3张牌,那么肯定要以一种顺序来播放攻击动画.我是以从左到右的方式. 我的解决方案是向每张牌都传递一个延时參数,然后在runAction ...
- CUDA学习之从CPU架构说起
最近要学习GPU编程,就去英伟达官网下载CUDA, 遇到的第一个问题就是架构的选择 所以我学习的CUDA的第一步是从学习认识CPU架构开始的,x86-64简称x64,是64位版的x86指令集,向前兼容 ...
- E. Reachability from the Capital(tarjan+dfs)
求联通分量个数,在dfs一次 #include <iostream> #include <algorithm> #include <cstring> #includ ...