G - KiKi's K-Number(树状数组求区间第k大)
Push: Push a given element e to container
Pop: Pop element of a given e from container
Query: Given two elements a and k, query the kth larger number which greater than a in container;
Although Kiki is very intelligent, she can not think of how to do it, can you help her to solve this problem?
number is an integer m (1 <= m <100000), means that the number of
operation to do. The next m lines, each line will be an integer p at the
beginning, p which has three values:
If p is 0, then there will be an integer e (0 <e <100000), means press element e into Container.
If p is 1, then there will be an integer e (0 <e <100000), indicated that delete the element e from the container
If p is 2, then there will be two integers a and k (0 <a
<100000, 0 <k <10000),means the inquiries, the element is
greater than a, and the k-th larger number.
OutputFor each deletion, if you want to delete the element which
does not exist, the output "No Elment!". For each query, output the
suitable answers in line .if the number does not exist, the output "Not
Find!".Sample Input
5
0 5
1 2
0 6
2 3 2
2 8 1
7
0 2
0 2
0 4
2 1 1
2 1 2
2 1 3
2 1 4
Sample Output
No Elment!
6
Not Find!
2
2
4
Not Find!
题意:有3种操作:0.将所给元素压进容器。1.将所给元素从容器中删除,若没有输出No Elment! 2.找比a大的数中第k大的数(可用二分逼近)
#include<iostream>
#include<cstring>
#include<vector>
#include<string>
#include<stdio.h>
using namespace std;
typedef long long ll;
int lowbit(int x){return x&-x;}
const int maxn=;
int c[maxn+];
int n,m;
void update(int x,int v)
{
for(int i=x;i<=maxn;i+=lowbit(i))
c[i]+=v;
}
int sum(int x)
{
int ans=;
for(int i=x;i>=;i-=lowbit(i))
ans+=c[i];
return ans;
} int main()
{
ios::sync_with_stdio();
int m;
while(cin>>m){
memset(c,,sizeof(c));
while(m--){
int op,x,k;
cin>>op;
if(op==){
cin>>x;
update(x,);
}
else if(op==){
cin>>x;
if(sum(x)-sum(x-)==)cout<<"No Elment!"<<endl;
else update(x,-);
}
else{
cin>>x>>k;
int l=x+,r=,ans=-;
while(l<=r){
int mid=(l+r)/;
if(sum(mid)-sum(x)>=k)//如果[x+1,mid]区间比x大的超过k个,说明答案可以更小
ans=mid,r=mid-;
else l=mid+;//否则答案需要更大
}
if(ans==-)cout<<"Not Find!"<<endl;
else cout<<ans<<endl;
}
}
}
return ;
}
2:线段树版本(不能简单的用二分了,需要直接写个递归函数,有点像权值线段树的意思了)
#include<iostream>
#include<cstring>
#include<vector>
#include<string>
#include<stdio.h>
using namespace std;
typedef long long ll;
int lowbit(int x){return x&-x;}
const int maxn=;
int tree[maxn<<];
void update(int l,int r,int x,int v,int rt)
{
if(l==r){
if(v==)tree[rt]++;
else{
if(tree[rt]==)
cout<<"No Elment!"<<endl;
else
tree[rt]--;
}
return ;
}
int mid=(l+r)/;
if(x<=mid)update(l,mid,x,v,rt*);
else update(mid+,r,x,v,rt*+);
tree[rt]=tree[rt*]+tree[rt*+];
}
int querysum(int l,int r,int L,int R,int rt)
{
if(L<=l&&R>=r)return tree[rt];
int mid=(l+r)/;
int ans=;
if(L<=mid)ans+=querysum(l,mid,L,R,rt*);
if(R>=mid+)ans+=querysum(mid+,r,L,R,rt*+);
return ans;
}
int query(int l,int r,int k,int rt)
{
if(l==r)return l;
int mid=(l+r)/;
if(k<=tree[rt*])return query(l,mid,k,rt*);
else return query(mid+,r,k-tree[rt*],rt*+);
}
int main()
{
int m;
int n=;
while(scanf("%d", &m) != EOF){
memset(tree,,sizeof(tree));
while(m--){
int op,x,k;
scanf("%d",&op);
if(op==){
scanf("%d",&x);
update(,n,x,,);
}
else if(op==){
scanf("%d",&x);
update(,n,x,-,);
}
else{
scanf("%d%d",&x,&k);
int pos=querysum(,n,,x,);
int ans=query(,n,pos+k,);
if(ans>=maxn)cout<<"Not Find!"<<endl;
else cout<<ans<<endl;
}
}
}
return ;
}
G - KiKi's K-Number(树状数组求区间第k大)的更多相关文章
- HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number ...
- HDU 1394 Minimum Inversion Number (树状数组求逆序对)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题目让你求一个数组,这个数组可以不断把最前面的元素移到最后,让你求其中某个数组中的逆序对最小是多 ...
- 树状数组求区间和模板 区间可修改 参考题目:牛客小白月赛 I 区间
从前有个东西叫树状数组,它可以轻易实现一些简单的序列操作,比如单点修改,区间求和;区间修改,单点求值等. 但是我们经常需要更高级的操作,比如区间修改区间查询.这时候树状数组就不起作用了,只能选择写一个 ...
- 【POJ2104】【整体二分+树状数组】区间第k大
Description You are working for Macrohard company in data structures department. After failing your ...
- [Split The Tree][dfs序+树状数组求区间数的种数]
Split The Tree 时间限制: 1 Sec 内存限制: 128 MB提交: 46 解决: 11[提交] [状态] [讨论版] [命题人:admin] 题目描述 You are given ...
- 【BZOJ】1012: [JSOI2008]最大数maxnumber 树状数组求区间最值
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1012 题意:维护一个数列,开始时没有数值,之后会有两种操作, Q L :查询数列末 ...
- 【BZOJ1012】【树状数组求区间最值】最大数maxnumber
Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. ...
- 主席树套树状数组 动态区间第k小
先打上代码以后更新解释 #include <cstdio> #include <iostream> #include <algorithm> #include &l ...
- UVA11525 Permutation[康托展开 树状数组求第k小值]
UVA - 11525 Permutation 题意:输出1~n的所有排列,字典序大小第∑k1Si∗(K−i)!个 学了好多知识 1.康托展开 X=a[n]*(n-1)!+a[n-1]*(n-2)!+ ...
随机推荐
- Mybatis 持久化,持久层
持久化 持久化是将程序数据在持久状态和瞬时状态间转换的机制. 即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘).持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中.X ...
- outlook 2013邮件在服务器保留副本
用outlook2013来收邮件确实是比较方便,但是它收邮件默认设置是:当outlook2013将在线邮箱的邮件下载至本机计算机之后,它就会删除在线邮箱中的邮件.不知道是不是以前邮箱容量比较小,所以要 ...
- 《C Primer Plus》- 第一章 初试C语言
本笔记写于2020年1月25日. 从今天开始,我要全面的.彻底的将未来计划中所有的知识重新规划学习一遍,并整理成一套全面的笔记体系.为我将来的职业打下坚实的基础.而所有的一切从C语言开始. 本系列文章 ...
- APP-计算器
在网课上学习了计算器的制作方法,并自己做了小常识,看完一便后,感觉自己会了,思想也明白了,但是当关掉视频真正开始做的时候会发向许多的问题,自己在前的好多语法用的并不是很熟练,但是反复的查阅资料,观看教 ...
- Django2.0——Form组件简单总结
Django提供了一个Form组件来配和前端的表单进行使用,Form有两个强大的功能,分别是生成HTML代码和验证数据的合法性.通常我们不会用其第一个功能,因为前端的设计可以做出更加精美且多样的表单页 ...
- List中常用的linq操作
[Serializable] public class Product { public Product() { } public Product(string id,string pname,int ...
- Python笔记_第四篇_高阶编程_高阶函数_3.sorted
1. sorted函数: 常用的排序分:冒泡排序.选择排序.快速排序.插入排序.计数器排序 实例1:普通排序 # 普通排序 list1 = [,,,,] list2 = sorted(list1) # ...
- 寒假day04
今天编写了毕设系统中的专家画像模块,实现了人员标签的建立与划分,同时刷了牛客网的面试相关题目. 1.如果系统的umask设置为244,创建一个新文件后,它的权限:(C) --w-r--r-- -r-x ...
- netty 百度网盘 密码
netty基础 https://pan.baidu.com/s/1v_ME49LIef1Kwga8z2QbDw?spm=a1z09.2.0.0.680b2e8d5LI8S0 zb7u mina n ...
- Google Guava入门教程
以下资料整理自网络 一.Google Guava入门介绍 引言 Guava 工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] .缓存 [cachi ...