【传送门: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小的数Ⅱ的更多相关文章

  1. *HDU2852 树状数组(求第K小的数)

    KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  2. 计算序列中第k小的数

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4046399.html 使用分治算法,首先选择随机选择轴值pivot,并使的序列中比pivot ...

  3. [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 ...

  4. #7 找出数组中第k小的数

    「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...

  5. 无序数组求第k大/第k小的数

    根据http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html 博客中所总结的7种解法,我挑了其中的解法3和解法6进行了实现. 解法3: ...

  6. 查找第K小的数 BFPRT算法

    出处 http://blog.csdn.net/adong76/article/details/10071297 BFPRT算法是解决从n个数中选择第k大或第k小的数这个经典问题的著名算法,但很多人并 ...

  7. 基于快速排序思想partition查找第K大的数或者第K小的数。

    快速排序 下面是之前实现过的快速排序的代码. function quickSort(a,left,right){ if(left==right)return; let key=partition(a, ...

  8. 算法---数组总结篇2——找丢失的数,找最大最小,前k大,第k小的数

    一.如何找出数组中丢失的数 题目描述:给定一个由n-1个整数组成的未排序的数组序列,其原始都是1到n中的不同的整数,请写出一个寻找数组序列中缺失整数的线性时间算法 方法1:累加求和 时间复杂度是O(N ...

  9. cogs930找第k小的数(k-th number)

    cogs930找第k小的数(k-th number) 原题链接 题解 好题... 终极版是bzoj3065(然而并不会) 先讲这个题... 维护\(n+1\)个值域线段树(用主席树),标号\(0\) ...

随机推荐

  1. java zyUpload 实现多文件上传

    1.html部分 <form enctype="multipart/form-data"> <label>请选择文件</label> <i ...

  2. django 用户上传文件media的存储访问配置1

    1. 首先新建文件夹media  后 在项目setting中具体配置: MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media ...

  3. 题解 洛谷 P4047 【[JSOI2010]部落划分】

    我觉得几乎就是一道最小生成树模板啊... 题解里许多大佬都说选第n-k+1条边,可我觉得要这么讲比较容易理解 (虚边为能选的边,实边为最小生成树) 令n=5,k=2,(1,3)<(1,2)< ...

  4. SpringMVC+Jquery -页面异步载入数据

    背景: 做项目时涉及到页面.当我打算在controller中传一个list到页面,然后通过<c:foreach>循环遍历出来时,同事说:你这样每次都要刷新.这都是几百年前使用的技术了.你用 ...

  5. Android中的AsyncTask异步任务的简单实例

    在 Android中的AsyncTask异步任务的简介 一文中.已经对 安卓 异步任务操作做了简单的介绍.这里,直接将上文中的异步任务做了一个实例.实现异步操作更新UI线程,相比开启子线程更新来说逻辑 ...

  6. ASCII中的控制字符含义

    十进制 十六进制 控制字符 转义字符 说明 Ctrl + 下列字母 0 00 NUL \0 Null character(空字符) @ 1 01 SOH   Start of Header(标题開始) ...

  7. The broken pedometer-纯暴力枚举

    The broken pedometer Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu i ...

  8. poj_2481,Cows,树状数组

    将e按从大到小排序,统计前i-1个中比 #include<iostream> #include<cstdio> #include<cstring> #include ...

  9. nyoj--46--最少乘法次数(数学+技巧)

    最少乘法次数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 给你一个非零整数,让你求这个数的n次方,每次相乘的结果可以在后面使用,求至少需要多少次乘.如24:2*2=2 ...

  10. 36.创建自定义的指令directive

    转自:https://www.cnblogs.com/best/tag/Angular/ 1. <html> <head> <meta charset="utf ...