【划分树】 POJ 2104 HDU 2665 K-th Number 裸题
生活随笔
收集整理的這篇文章主要介紹了
【划分树】 POJ 2104 HDU 2665 K-th Number 裸题
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
了解了。。。。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> typedef long long LL; const int MAXN = 100999;//點(diǎn)數(shù)的最大值 const int MAXM = 1000010;//邊數(shù)的最大值 const LL INF = 1152921504; /* * 劃分樹(shù)(查詢區(qū)間第k小) */ int tree[20][MAXN];//表示每層每個(gè)位置的值 int sorted[MAXN];//已經(jīng)排序好的數(shù) int toleft[20][MAXN];//toleft[p][i]表示第p層從1到i有數(shù)分入左邊 void build(int l,int r,int dep) {if(l == r)return;int mid = (l+r)>>1;int same = mid - l + 1;//表示等于中間值而且被分入左邊的個(gè)數(shù)for(int i = l; i <= r; i++) //注意是l,不是oneif(tree[dep][i] < sorted[mid])same--;int lpos = l;int rpos = mid+1;for(int i = l; i <= r; i++){if(tree[dep][i] < sorted[mid])tree[dep+1][lpos++] = tree[dep][i];else if(tree[dep][i] == sorted[mid] && same > 0){tree[dep+1][lpos++] = tree[dep][i];same--;}elsetree[dep+1][rpos++] = tree[dep][i];toleft[dep][i] = toleft[dep][l-1] + lpos - l;}build(l,mid,dep+1);build(mid+1,r,dep+1); } //查詢區(qū)間第k小的數(shù),[L,R]是大區(qū)間,[l,r]是要查詢的小區(qū)間 int query(int L,int R,int l,int r,int dep,int k) {if(l == r)return tree[dep][l];int mid = (L+R)>>1;int cnt = toleft[dep][r] - toleft[dep][l-1];//區(qū)間內(nèi)有多少個(gè)被分到左區(qū)間if(cnt >= k)//左兒子里的樹(shù)>=k,在左邊找{int newl = L + toleft[dep][l-1] - toleft[dep][L-1];//改變區(qū)間,使得新區(qū)間包含l ,r 里面的數(shù)int newr = newl + cnt - 1;return query(L,mid,newl,newr,dep+1,k);}else{int newr = r + toleft[dep][R] - toleft[dep][r];//右邊有(toleft[dep][R] - toleft[dep][r])個(gè)在左區(qū)間,可以向右移動(dòng)這么多int newl = newr - (r-l-cnt);return query(mid+1,R,newl,newr,dep+1,k-cnt);} } int main() {int n,m;// freopen("in.txt","r",stdin);while(scanf("%d%d",&n,&m)!=EOF){memset(tree,0,sizeof(tree));for(int i = 1; i <= n; i++){scanf("%d",&tree[0][i]);sorted[i] = tree[0][i];}sort(sorted+1,sorted+n+1);build(1,n,0);while(m--){int l,r,k;scanf("%d%d%d",&l,&r,&k);printf("%d\n",query(1,n,l,r,0,k));}}return 0;}轉(zhuǎn)載于:https://www.cnblogs.com/kewowlo/p/4002574.html
總結(jié)
以上是生活随笔為你收集整理的【划分树】 POJ 2104 HDU 2665 K-th Number 裸题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 运维的85条军规
- 下一篇: Android 再谈handler