您的位置:首页 > 其它

【POJ】2104 K-th Number

2016-02-13 23:57 246 查看
区间第K大数。
主席树可解。

/* 2104 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000")

#define sti                set<int>
#define stpii            set<pair<int, int> >
#define mpii            map<int,int>
#define vi                vector<int>
#define pii                pair<int,int>
#define vpii            vector<pair<int,int> >
#define rep(i, a, n)     for (int i=a;i<n;++i)
#define per(i, a, n)     for (int i=n-1;i>=a;--i)
#define clr                clear
#define pb                 push_back
#define mp                 make_pair
#define fir                first
#define sec                second
#define all(x)             (x).begin(),(x).end()
#define SZ(x)             ((int)(x).size())
// #define lson            l, mid, rt<<1
// #define rson            mid+1, r, rt<<1|1

const int maxn = 1e5+5;
const int maxm = maxn * 50;
int T[maxn];
int lson[maxm], rson[maxm], c[maxm];
int a[maxn], b[maxn];
int n, m;
int tot = 0;

int Build(int l, int r) {
int rt = tot++;

c[rt] = 0;
if (l == r)
return rt;

int mid = (l + r) >> 1;

lson[rt] = Build(l, mid);
rson[rt] = Build(mid+1, r);

return rt;
}

int Insert(int rt, int x, int delta) {
int nrt = tot++, ret = nrt;
int l = 0, r = m - 1, mid;

c[nrt] = c[rt] + delta;
while (l < r) {
mid = (l + r) >> 1;
if (x <= mid) {
lson[nrt] = tot++;
rson[nrt] = rson[rt];
nrt = lson[nrt];
rt = lson[rt];
r = mid;
} else {
lson[nrt] = lson[rt];
rson[nrt] = tot++;
nrt = rson[nrt];
rt = rson[rt];
l = mid + 1;
}
c[nrt] = c[rt] + delta;
}

return ret;
}

int Query(int lrt, int rrt, int k) {
int l = 0, r = m - 1, mid;
int tmp;

while (l < r) {
mid = (l + r) >> 1;
tmp = c[lson[rrt]] - c[lson[lrt]];
if (tmp >= k) {
lrt = lson[lrt];
rrt = lson[rrt];
r = mid;
} else {
k -= tmp;
lrt = rson[lrt];
rrt = rson[rrt];
l = mid + 1;
}
}

return l;
}

int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif

int n, q;

scanf("%d %d", &n, &q);
rep(i, 0, n) {
scanf("%d", &a[i]);
b[i] = a[i];
}
sort(b, b+n);
m = unique(b, b+n) - b;
T[0] = Build(0, m-1);
rep(i, 0, n) {
int id = lower_bound(b, b+m, a[i]) - b;
T[i+1] = Insert(T[i], id, 1);
}

int l, r, kth;
int ans;

while (q--) {
scanf("%d %d %d", &l, &r, &kth);
ans = b[Query(T[l-1], T[r], kth)];
printf("%d\n", ans);
}

#ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif

return 0;
}


划分树可解。

/* 2104 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000")

#define sti                set<int>
#define stpii            set<pair<int, int> >
#define mpii            map<int,int>
#define vi                vector<int>
#define pii                pair<int,int>
#define vpii            vector<pair<int,int> >
#define rep(i, a, n)     for (int i=a;i<n;++i)
#define per(i, a, n)     for (int i=n-1;i>=a;--i)
#define clr                clear
#define pb                 push_back
#define mp                 make_pair
#define fir                first
#define sec                second
#define all(x)             (x).begin(),(x).end()
#define SZ(x)             ((int)(x).size())
// #define lson            l, mid, rt<<1
// #define rson            mid+1, r, rt<<1|1
#define LL                __int64

const int maxn = 1e5+5;
int order[maxn];
int val[18][maxn];
int toLeft[18][maxn];

void Build(int l, int r, int dep) {
if (l == r)
return ;

int mid = (l + r) >> 1;
int same = mid - l + 1;

rep(i, l, r+1) {
if (val[dep][i] < order[mid])
--same;
}

int lpos = l, rpos = mid + 1;
rep(i, l, r+1) {
if (val[dep][i] < order[mid]) {
val[dep+1][lpos++] = val[dep][i];
} else if (val[dep][i]==order[mid] && same>0) {
val[dep+1][lpos++] = val[dep][i];
--same;
} else {
val[dep+1][rpos++] = val[dep][i];
}
toLeft[dep][i] = toLeft[dep][l-1] + lpos - l;
}

Build(l, mid, dep+1);
Build(mid+1, r, dep+1);
}

int Query(int l, int r, int k, int L, int R, int dep) {
if (l == r)
return val[dep][l];

int mid = (L + R) >> 1;
int tmp = toLeft[dep][r] - toLeft[dep][l-1];

if (tmp >= k) {
int ll = L + toLeft[dep][l-1] - toLeft[dep][L-1];
int rr = ll + tmp - 1;

return Query(ll, rr, k, L, mid, dep+1);
} else {
k-= tmp;

int rr = r + toLeft[dep][R] - toLeft[dep][r];
int ll = rr - (r-l+1-tmp) + 1;

return Query(ll, rr, k, mid+1, R, dep+1);
}
}

int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif

int n, q;
int l, r, kth;
int ans;

scanf("%d %d", &n, &q);
rep(i, 1, n+1) {
scanf("%d", &val[0][i]);
order[i] = val[0][i];
}
sort(order+1, order+1+n);
Build(1, n, 0);
while (q--) {
scanf("%d %d %d", &l, &r, &kth);
ans = Query(l, r, kth, 1, n, 0);
printf("%d\n", ans);
}

#ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif

return 0;
}


数据发生器。

from copy import deepcopy
from random import randint, shuffle
import shutil
import string

def GenDataIn():
with open("data.in", "w") as fout:
t = 1
bound = 10**3
# fout.write("%d\n" % (t))
for tt in xrange(t):
n = randint(100, 200)
q = randint(100, 200)
fout.write("%d %d\n" % (n, q))
L = []
for i in xrange(n):
x = randint(1, bound)
L.append(x)
fout.write(" ".join(map(str, L)) + "\n")
for i in xrange(q):
l = randint(1, n)
r = randint(l, n)
k = randint(1, r-l+1)
fout.write("%d %d %d\n" % (l, r, k))

def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName)

if __name__ == "__main__":
GenDataIn()
MovDataIn()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: