POJ2104 K-th Number [分块做法]
传送:主席树做法http://www.cnblogs.com/candy99/p/6160704.html
做那倒带修改的主席树时就发现分块可以做,然后就试了试
思想和教主的魔法差不多,只不过那个是求>=v的有几个
既然一个数v的名次可以求,我们二分这个数就行了啊
然而......
首先,你二分到的这个数不一定在区间里出现过
比如 1 2 5 8 9
4和5的名次都是3
于是,我修改了某个区间名次的定义:
“如果一个数的名次是x,但是区间中没有次数,那么他的名次为x-1”
实现上只需要find里return l-t+(b[l]==v) 等于说明出现过
然而
该死不写了鬼知道怎么回事用主席树就行了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e5+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,Q,a[N],bl,m,b[N],pos[N];
int mp[N];
void reset(int x){
int l=(x-)*bl+,r=min(x*bl,n);
for(int i=l;i<=r;i++) b[i]=a[i];
sort(b+l,b+r+);
}
int flag;
int find(int x,int v){
int l=(x-)*bl+,r=min(x*bl,n),t=l;
while(l<=r){
int mid=(l+r)>>;
if(b[mid]<v) l=mid+;
else r=mid-;
}
if(b[l]==v) flag=;
return l-t+;//!
}
int rank(int l,int r,int v){
int ans=;
flag=;
if(pos[l]==pos[r]){
for(int i=l;i<=r;i++) if(a[i]<=v) ans++,flag=flag||a[i]==v;
}else{
int t=pos[l]*bl;
for(int i=l;i<=t;i++) if(a[i]<=v) ans++,flag=flag||a[i]==v;
for(int i=(pos[r]-)*bl+;i<=r;i++) if(a[i]<=v) ans++,flag=flag||a[i]==v;
for(int i=pos[l]+;i<pos[r];i++) ans+=find(i,v);
}
if(!flag) ans--;
return ans;
}
int query(int ql,int qr,int k){
int l=,r=n;
while(l<=r){
int mid=(l+r)>>;
int t=rank(ql,qr,mp[mid]);
if(t<k) l=mid+;
else r=mid-;
}
return l;
}
int main(){
freopen("in.txt","r",stdin);
freopen("1.out","w",stdout);
n=read();Q=read();
bl=sqrt(n);
m=n/bl;if(n%bl) m++;
for(int i=;i<=n;i++) a[i]=mp[i]=read(),pos[i]=(i-)/bl+;
for(int i=;i<=m;i++) reset(i);
sort(mp+,mp++n);
while(Q--){
int i=read(),j=read(),k=read();
printf("%d\n",mp[query(i,j,k)]);
}
}
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000") using namespace std;
#define MAX 100005
#define MAXN 1000005
#define maxnode 15
#define sigma_size 30
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lrt rt<<1
#define rrt rt<<1|1
#define middle int m=(r+l)>>1
#define LL long long
#define ull unsigned long long
#define mem(x,v) memset(x,v,sizeof(x))
#define lowbit(x) (x&-x)
#define pii pair<int,int>
#define bits(a) __builtin_popcount(a)
#define mk make_pair
#define limit 10000 //const int prime = 999983;
const int INF = 0x3f3f3f3f;
const LL INFF = 0x3f3f;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-;
const LL mod = 1e9+;
const ull mx = ; /*****************************************************/
inline void RI(int &x) {
char c;
while((c=getchar())<'' || c>'');
x=c-'';
while((c=getchar())>='' && c<='') x=(x<<)+(x<<)+c-'';
}
/*****************************************************/ int a[MAX];
int b[MAX];
int c[MAX];
int tmp;
bool judge(int x,int l,int r,int k){
int a1=l/tmp;
int a2=r/tmp;
int sum=;//for(int i=l;i<=r;i++) printf("%d ",a[i]);puts("");
if(a1==a2){
for(int i=l;i<=r;i++) if(a[i]<=c[x]) sum++;
if(sum>=k) return true;
return false;
}
for(int i=a1+;i<a2;i++){
sum+=upper_bound(b+i*tmp,b+(i+)*tmp,c[x])-b-i*tmp;
}
for(int i=l;i<(a1+)*tmp;i++) if(a[i]<=c[x]) sum++;
for(int i=a2*tmp;i<=r;i++) if(a[i]<=c[x]) sum++; //printf("ra %d %d %d %d\n",l,r,c[x],sum);
if(sum>=k) return true;
return false;
} int main(){
freopen("in.txt","r",stdin);
freopen("2.out","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
tmp=sqrt(n);
for(int i=;i<n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
c[i]=a[i];
}
sort(c,c+n);
for(int i=;i*tmp<n;i++){
if((i+)*tmp<=n) sort(b+i*tmp,b+(i+)*tmp);
else sort(b+i*tmp,b+n);
}
while(m--){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
int ll=,rr=n-;
while(ll<=rr){
int mid=(ll+rr)>>;
if(judge(mid,l-,r-,k)) rr=mid-;
else ll=mid+;
}
printf("%d\n",c[ll]);
}
return ;
}
别人的AC代码
POJ2104 K-th Number [分块做法]的更多相关文章
- [POJ2104] K – th Number (可持久化线段树 主席树)
题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...
- ZOJ 2112 Dynamic Rankings(带修改的区间第K大,分块+二分搜索+二分答案)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- 【POJ2104】K-th Number
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABToAAAJ2CAIAAADwi6oDAAAgAElEQVR4nOy9a5Pj1nnvi0/Q71Llj3
- C++之路进阶——poj2104(K-th Number)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 44537 Accepted: 14781 Ca ...
- luo3372线段树模板的分块做法
题目大意 请你维护一个有n个元素的整数序列,要求支持区间查询&区间修改 对于100%的数据,\(1<=n<=10^5\) 分析 正常做法是线段树维护区间修改.区间查询,今天我要讲的 ...
- 【poj2104】K-th Number 主席树
题目描述 You are working for Macrohard company in data structures department. After failing your previou ...
- 【POJ2104】K-th Number(主席树)
题意:有n个数组成的序列,要求维护数据结构支持在线的下列两种操作: 1:单点修改,将第x个数修改成y 2:区间查询,询问从第x个数到第y个之间第K大的数 n<=100000,a[i]<=1 ...
- HDU 4366 Successor 分块做法
http://acm.hdu.edu.cn/showproblem.php?pid=4366 今日重新做了这题的分块,果然是隔太久了,都忘记了.. 首先,用DFS序变成一维的问题 关键是它有两个权值, ...
- 「BZOJ3065」带插入区间K小值 [分块]
考虑分块,每个块都是用 链表 维护的,并保证 \(size\) 和分块相当. 我们考虑一下怎么去查询,很显然,可以对值域分块,单点修改,记录前缀和,完全ojbk了,对每个块维护一个 \(pre , p ...
随机推荐
- Python模拟登陆新浪微博
上篇介绍了新浪微博的登陆过程,这节使用Python编写一个模拟登陆的程序.讲解与程序如下: 1.主函数(WeiboMain.py): import urllib2 import cookielib i ...
- angular2系列教程(五)Structural directives、再谈组件生命周期
今天,我们要讲的是structural directives和组件生命周期这两个知识点.structural directives顾名思义就是改变dom结构的指令.著名的内建结构指令有 ngIf, n ...
- CentOS7安装iptables防火墙
CentOS7默认的防火墙不是iptables,而是firewalle. 安装iptable iptable-service #先检查是否安装了iptables service iptables st ...
- Java 序列化与反序列化
1.什么是序列化?为什么要序列化? Java 序列化就是指将对象转换为字节序列的过程,而反序列化则是只将字节序列转换成目标对象的过程. 我们都知道,在进行浏览器访问的时候,我们看到的文本.图片.音频. ...
- Nginx最大客户连接数算法一些遐想
Nginx最大客户连接数算法一些遐想 现在很多互联网公司都在使用nginx,并且替换掉以前的Apache,nginx的优点就不说了,浅聊两句nginx的某些配置参数,找到这些参数设置的目的和关联性,并 ...
- jQuery使用
jQuery jQuery是一个快速,小,功能丰富的JavaScript库. 它使 HTML文档遍历和操作.事件处理. 动画和Ajax更简单和易于使用的API,在工作 众多的浏览器. 和多功能性的结合 ...
- asp.net MVC4——省市三级联动
controller: public ActionResult GetCity(string id) { AreaService _areaSvc = new AreaService(); List& ...
- python之最强王者(4)——字符串
1.Python 中文编码 前面章节中我们已经学会了如何用 Python 输出 "Hello, World!",英文没有问题,但是如果你输出中文字符"你好,世界" ...
- js类型检测总结
类型检测: 类和对象: Call,Apply,Bind
- 利用私有的库MobileCoreServices检测正在安装的应用
利用的私有库检测正在安装的app 分为两步:第一,通过placeholderApplications获得所有的正在安装的app的信息 第二,遍历正在安装的app的信息,根据名称获得你想检测的app是否 ...