POJ2104 区间第k小
题意就是区间第k大……
题解:
前段时间用主席树搞掉了……
如今看到划分树,是在想来写一遍,结果18号对着学长的代码调了一上午连样例都没过,好桑心……
今天在做NOI2010超级钢琴,忽然发现用划分树很直观,果断决定再战划分树
对着网上的c++代码抄了一遍,A了,可是这编程复杂度有点高,忽然又看见盾哥的代码
很简短,和我原先的代码差不多,他怎么能A了呢……(后来发现区间第k小,我却写的第k大……sb啊)
考虑到盾哥的程序用到了离散化,因此没有考虑存在两个数相等的情况,这样就使代码减少很多
我报着试一试的心态把我认为肯定对的代码随机生成了几组大数据和盾哥的程序对拍,然后就对上了
好的,以后就用盾哥的程序
代码:
c++翻译来的:
- var s,t:array[..,..] of longint;
- a,rk:array[..] of longint;
- i,n,m,x,y,k,j:longint;
- procedure sort(l,r:longint);
- var i,j,m,temp:longint;
- begin
- i:=l;j:=r;m:=a[(i+j)>>];
- repeat
- while a[i]<m do inc(i);
- while a[j]>m do dec(j);
- if i<=j then
- begin
- temp:=a[i];a[i]:=a[j];a[j]:=temp;
- inc(i);dec(j);
- end;
- until i>j;
- if i<r then sort(i,r);
- if j>l then sort(l,j);
- end;
- procedure init;
- begin
- readln(n,m);
- for i:= to n do read(a[i]);t[]:=a;
- sort(,n);
- end;
- procedure build(h,l,r:longint);
- var mid,i,lp,rp,lm:longint;
- begin
- mid:=(l+r)>>;lm:=mid-l+;lp:=l;rp:=mid+;
- for i:=l to mid do
- if a[i]<a[mid] then dec(lm);
- for i:=l to r do
- begin
- if i=l then s[h,i]:= else s[h,i]:=s[h,i-];
- if t[h,i]=a[mid] then
- begin
- if lm<> then
- begin
- dec(lm);inc(s[h,i]);t[h+,lp]:=t[h,i];inc(lp);
- end
- else begin t[h+,rp]:=t[h,i];inc(rp);end;
- end
- else
- if t[h,i]<a[mid] then begin inc(s[h,i]);t[h+,lp]:=t[h,i];inc(lp);end
- else begin t[h+,rp]:=t[h,i];inc(rp);end;
- end;
- if l=r then exit;
- build(h+,l,mid);
- build(h+,mid+,r);
- end;
- function find(h,l,r,x,y,k:longint):longint;
- var mid,ll,rr:longint;
- begin
- if l=r then exit(t[h,l]);
- mid:=(l+r)>>;
- if l=x then ll:= else ll:=s[h,x-];rr:=s[h,y]-ll;
- if rr>=k then exit(find(h+,l,mid,l+ll,l+ll+rr-,k))
- else exit(find(h+,mid+,r,mid++x-l-ll,mid++y-l-ll-rr,k-rr));
- end;
- procedure main;
- begin
- build(,,n);
- for i:= to m do
- begin
- readln(x,y,k);
- writeln(find(,,n,x,y,k));
- end;
- end;
- begin
- init;
- main;
- end.
盾哥的:
- program poj2104; const maxn=;
- var
- a,b:array[..maxn] of longint;
- s,d:array[..,..maxn] of longint;
- n,m,i,j,x,y,z,ls,rs,mid,p:longint;
- procedure sort(l,r:longint); var i,j,x,y:longint;
- begin
- i:=l;j:=r;x:=a[(i+j)>> ];
- repeat
- while b[a[i]]<b[x] do inc(i);
- while b[a[j]]>b[x] do dec(j);
- if i<=j then begin
- y:=a[i];a[i]:=a[j];a[j]:=y;
- inc(i);dec(j);
- end;
- until i>j;
- if l<j then sort(l,j);
- if i<r then sort(i,r);
- end;
- procedure buildtree(h,l,r:longint);var mid:longint;
- begin
- if l=r then exit;
- mid:=(l+r+)>> ;p:=;
- for i:=l to r do
- if d[h,i]<mid then begin
- d[h+,l+p]:=d[h,i];
- inc(p);s[h,i]:=p;
- end else begin
- d[h+,mid+i-l-p]:=d[h,i];
- s[h,i]:=p;
- end;
- buildtree(h+,l,mid-);
- buildtree(h+,mid,r);
- end;
- function find(h,ll,rr,l,r,k:longint):longint;
- begin
- if l=r then exit(d[h,r]);
- if l=ll then ls:= else ls:=s[h,l-];
- rs:=s[h,r];mid:=(ll+rr+)>> ;
- if rs-ls<k
- then find:=find(h+,mid,rr,l-ll-ls+mid,r-ll-rs+mid,k-rs+ls)
- else find:=find(h+,ll,mid-,ls+ll,rs+ll-,k);
- end;
- begin
- readln(n,m);
- for i:= to n do begin read(b[i]);a[i]:=i; end;
- sort(,n);
- for i:= to n do d[,a[i]]:=i;
- buildtree(,,n);
- for i:= to m do begin
- readln(x,y,z);
- writeln(b[a[find(,,n,x,y,z)]]);
- end;
- end.
我最先抄的:
- const maxn=+;
- type arrtype=array[..maxn] of longint;
- var s,z:array[..,..maxn] of longint;
- a,b,rk:arrtype;
- i,j,n,m,x,y,k:longint;
- procedure sort(var a:arrtype;l,r:longint);
- var i,j,m,temp:longint;
- begin
- i:=l;j:=r;m:=a[(i+j)>>];
- repeat
- while a[i]<m do inc(i);
- while a[j]>m do dec(j);
- if i<=j then
- begin
- temp:=a[i];a[i]:=a[j];a[j]:=temp;
- temp:=rk[i];rk[i]:=rk[j];rk[j]:=temp;
- inc(i);dec(j);
- end;
- until i>j;
- if i<r then sort(a,i,r);
- if j>l then sort(a,l,j);
- end;
- procedure init;
- begin
- readln(n,m);
- for i:= to n do read(a[i]);readln;b:=a;
- for i:= to n do rk[i]:=i;
- sort(a,,n);
- end;
- procedure build(h,l,r:longint);
- var i,p,mid:longint;
- begin
- mid:=(l+r)>>;p:=;
- for i:=l to r do
- if z[h,i]<=mid then
- begin
- z[h+,l+p]:=z[h,i];
- inc(p);
- s[h,i]:=p;
- end
- else
- begin
- z[h+,mid++i-p-l]:=z[h,i];
- s[h,i]:=p;
- end;
- if l=r then exit;
- build(h+,l,mid);
- build(h+,mid+,r);
- end;
- function find(h,l,r,x,y,k:longint):longint;
- var ll,rr,mid:longint;
- begin
- if l=r then exit(z[h,l]);
- mid:=(l+r)>>;
- if l=x then ll:= else ll:=s[h,x-];rr:=s[h,y];
- if rr-ll>=k then exit(find(h+,l,mid,l+ll,l+rr-,k))
- else exit(find(h+,mid+,r,mid++x-l-ll,mid++y-l-rr,k-(rr-ll)));
- end;
- procedure main;
- begin
- for i:= to n do z[,rk[i]]:=i;
- build(,,n);
- for i:= to m do
- begin
- readln(x,y,k);
- writeln(b[rk[find(,,n,x,y,k)]]);
- end;
- end;
- begin
- init;
- main;
- end.
盾哥的代码风格确实比我好很多,值得学习
UPD:
c++
- #include<cstdio>
- #include<cmath>
- #include<cstring>
- #include<algorithm>
- #include<iostream>
- #define inf 1000000000
- #define maxn 100000+100
- #define maxm 100000
- using namespace std;
- int n,m,a[maxn],sa[maxn],t[][maxn],s[][maxn];
- inline int read()
- {
- int x=,f=;char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
- while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
- return x*f;
- }
- void build(int h,int l,int r)
- {
- int mid=(l+r)>>,num=;
- for(int i=l;i<=r;i++)
- if (t[h][i]<=mid)
- {
- t[h+][l+num]=t[h][i];
- s[h][i]=++num;
- }
- else
- {
- t[h+][mid++i-l-num]=t[h][i];
- s[h][i]=num;
- }
- if(l==r)return;
- build(h+,l,mid);
- build(h+,mid+,r);
- }
- int find(int h,int l,int r,int x,int y,int k)
- {
- if(l==r)return t[h][l];
- int mid=(l+r)>>,ll,rr;
- ll=(l==x)?:s[h][x-];rr=s[h][y];
- if(rr-ll>=k) return find(h+,l,mid,l+ll,l+rr-,k);
- else return find(h+,mid+,r,mid++x-l-ll,mid++y-l-rr,k-(rr-ll));
- }
- bool cmp(int x,int y)
- {
- return a[x]<a[y];
- }
- int main()
- {
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- n=read();m=read();
- for(int i=;i<=n;i++){a[i]=read();sa[i]=i;}
- sort(sa+,sa+n+,cmp);
- for(int i=;i<=n;i++)t[][sa[i]]=i;
- build(,,n);
- for(int i=;i<=m;i++)
- {
- int x,y,k;
- x=read();y=read();k=read();
- printf("%d\n",a[sa[find(,,n,x,y,k)]]);
- }
- return ;
- }
POJ2104 区间第k小的更多相关文章
- POJ2104 K-th Number —— 区间第k小 整体二分
题目链接:https://vjudge.net/problem/POJ-2104 K-th Number Time Limit: 20000MS Memory Limit: 65536K Tota ...
- 主席树总结(经典区间第k小问题)(主席树,线段树)
接着上一篇总结--可持久化线段树来整理吧.点击进入 这两种数据结构确实有异曲同工之妙.结构是很相似的,但维护的主要内容并不相同,主席树的离散化.前缀和等思想也要更难理解一些. 闲话 话说刚学习主席树的 ...
- ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解
题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...
- 【XSY2720】区间第k小 整体二分 可持久化线段树
题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...
- A - 低阶入门膜法 - K-th Number (主席树查询区间第k小)
题目链接:https://cn.vjudge.net/contest/284294#problem/A 题目大意:主席树查询区间第k小. 具体思路:主席树入门. AC代码: #include<i ...
- HDU 2665.Kth number 区间第K小
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- POJ 2014.K-th Number 区间第k小 (归并树)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 57543 Accepted: 19893 Ca ...
- Dynamic Rankings || 动态/静态区间第k小(主席树)
JYF大佬说,一星期要写很多篇博客才会有人看 但是我做题没有那么快啊QwQ Part1 写在前面 区间第K小问题一直是主席树经典题=w=今天的重点是动态区间第K小问题.静态问题要求查询一个区间内的第k ...
- 少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小
少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小 有一道题(BZOJ 1901)是这样的:n个数,m个询问,询问有两种:修改某个数/询问区间第k小. 不带修改的区间第k小用主席树很好写 ...
随机推荐
- CruiseControl.NET : Configuration Preprocessor
Original link: http://build.sharpdevelop.net/ccnet/doc/CCNET/Configuration%20Preprocessor.html http: ...
- Linux C 程序 函数,数组,指针,gdb调试器(SEVEN)
函数,数组,指针,gdb调试器 1.函数定义 如果明确指定返回类型,默认为int 参数传递:实参对形参的参数传递是单向的,实参只是把自己的值赋给形参. 形参的 ...
- JS到PHP使用RSA算法进行加密通讯
我们平时做用户登录表单提交,用户名密码都是明文直接POST到后端,这样很容易被别人从监听到. 在js上做rsa,感觉jsencrypt这个是封装的比较好的,但用起来还是遇到了些坑,所以踩进代码里填填坑 ...
- msSQL数据库备份还原小结
MSSQL自带了一个样例数据库pubs,就拿这个举例好了. 首先,来一次完全备份.对于数据量很大的数据库,这样的操作当然很费时间.所以我们采用每天凌晨4点一次完全备份,每个小时一个差异备份,每分钟一次 ...
- ContextMenuOpening 事件
ContextMenuOpening事件,不能在将要触发的目标ContextMenu中触发,只能包含 这个ContextMenu的父控件中触发该事件. 在ListView中,希望控制右键弹出菜单时,可 ...
- google map android api v2
我在这主要列举几个需要注意的问题: 1.需要注意使用的api版本的问题,例如google map android api v1就和v2差别很大,包括申请key方面,所以在搜索资料的时候一定注意版本问题 ...
- dataTable 禁止排序
$("#id").DataTable({ "ordering": false, // 禁止排序 });
- 021,lambda 表达式
021,lambda 表达式 匿名函数: 快速定义单行的最小函数,是从lisp借用来的,可以用在任何需要函数的地方 >>> def ds(x): return 2*x + ...
- Django路由
一.路由流程 1. 用户浏览器发出请求后,通过根url设置,去找urlpattern变量.在setting.py中对 ROOT_URLCONF进行配置,以确定根URLconf(URL configur ...
- SQL日期(转)
通常,你需要获得当前日期和计算一些其他的日期,例如,你的程序可能需要判断一个月的第一天或者最后一天.你们大部分人大概都知道怎样把日期进行分割 (年.月.日等),然后仅仅用分割出来的年.月.日等放在几个 ...