HDU2852【树状数组+二分】
2024-08-30 08:56:10
额。。有点遗忘了树状数组特性了。。印象中一直是前缀和,然后一定要记住树状数组是把给出的值(值太大可能可以离散化)也就是点到了区间,然后这个点存的值就是由自己来定了。
题意:
百度。
思路:
树状数组是用来标记的!值->区间点!
因为这里值重复是算的,所有树状数组存的是区间上该位置的个数。
0:插入则插入。
1:if(!(sum[x]-sum[x-1])) puts("NO...");
2:我们知道a(包括a)之前有多少个数x,求第k大的数,也就是求在树状数组中第x+k大的数。
sum[ans]=x+k。这个可以直接二分查找。
---
哦,还可以线段树,还是一样的,值->区间点,点所存的值自己定,这里也就是个数,差不多。但是这个查找第k大的数的位置,麻烦了。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=1e5+10;
int c[N],m; int lowbit(int x)
{
return x&(-x);
} void add(int x,int val)
{
while(x<=100000)
{
c[x]+=val;
x+=lowbit(x);
}
} int sum(int x)
{
int ans=0;
while(x>0)
{
ans+=c[x];
x-=lowbit(x);
}
return ans;
} int main()
{
while(~scanf("%d",&m))
{
int x;
int a,k;
memset(c,0,sizeof(c));
while(m--)
{
scanf("%d",&x);
if(x==0)
{
scanf("%d",&a);
add(a,1);
}
else if(x==1)
{
scanf("%d",&a);
if(sum(a)-sum(a-1)==0)
puts("No Elment!");
else
add(a,-1);
}
else
{
scanf("%d%d",&a,&k);
int p=sum(a)+k;
int left=1,right=100000;
while(left<right)
{
int mid=left+(right-left)/2;
if(sum(mid)>=p)
right=mid;
else
left=mid+1;
}
if(sum(left)>=p)
printf("%d\n",left);
else
puts("Not Find!");
}
}
}
return 0;
}
最新文章
- Object obj=new Object()的内存引用
- Winform开发框架中实现同时兼容多种数据库类型处理
- php高级
- linux库文件编写入门(笔记)
- uiscrollerview循环滚动(参考第三方库:HMBannerView)https://github.com/iunion/autoScrollBanner
- ZOJ3870 Team Formation
- 3.跟我学solr---使用solrj加入索引
- hdu 2191 悼念512四川汶川大地震遇难者——如今宝,感恩生活
- 多线程---优先级&;yield方法
- iOS开发实战-时光记账Demo 网络版
- Java NIO -- 通道 Channel
- Convert DataFrame string complex i to j python // “Cloning” row or column vectors
- POJ-3744 Scout YYF I (矩阵优化概率DP)
- SSL原理分析
- setTimeout问题
- android在开发过程中的数据库存储位置
- Remove Duplicates from Sorted List 去除链表中重复值节点
- 已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数
- flush清空输入输出流
- 2017 ICPC beijing F - Secret Poems