您的位置:首页 > 其它

【ZOJ】2112 Dynamic Rankings

2016-02-13 13:03 363 查看
树状数组套主席树模板题目。

/* 2112 */
#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

typedef struct {
int l, r, k;
int op;
} ques_t;

const int maxq = 10005;
const int maxn = 60005;
const int maxm = 2500010;
int n, q, m, tot;
int a[maxn], b[maxn];
int S[maxn], T[maxn];
int lson[maxm], rson[maxm], C[maxm];
ques_t Q[maxq];

void init() {
tot = m = 0;
}

void Build(int l, int r, int& rt) {
rt = tot++;
C[rt] = 0;
if (l == r)
return ;

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

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

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

C[nrt] = C[rt] + val;
while (l < r) {
mid = (l + r) >> 1;
if (p <= 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] + val;
}

return ret;
}

int lowest(int x) {
return -x & x;
}

int use[maxn];

void add(int x, int p, int delta) {
while (x <= n) {
S[x] = Insert(S[x], p, delta);
x += lowest(x);
}
}

int sum(int x) {
int ret = 0;

while (x) {
ret += C[lson[use[x]]];
x -= lowest(x);
}

return ret;
}

int Query(int L, int R, int k) {
int lrt = T[L-1];
int rrt = T[R];
int l = 0, r = m - 1, mid;
int tmp;

for (int i=L-1; i; i-=lowest(i))
use[i] = S[i];
for (int i=R; i; i-=lowest(i))
use[i] = S[i];

while (l < r) {
mid = (l + r) >> 1;
tmp = sum(R) - sum(L-1) + C[lson[rrt]] - C[lson[lrt]];
if (tmp >= k) {
for (int i=L-1; i; i-=lowest(i))
use[i] = lson[use[i]];
for (int i=R; i; i-=lowest(i))
use[i] = lson[use[i]];
r = mid;
lrt = lson[lrt];
rrt = lson[rrt];
} else {
for (int i=L-1; i; i-=lowest(i))
use[i] = rson[use[i]];
for (int i=R; i; i-=lowest(i))
use[i] = rson[use[i]];
k -= tmp;
l = mid + 1;
lrt = rson[lrt];
rrt = rson[rrt];
}
}

return l;
}

void solve() {
sort(b, b+m);
m = unique(b, b+m) - b;
Build(0, m-1, T[0]);
rep(i, 1, n+1) {
int id = lower_bound(b, b+m, a[i]) - b;
T[i] = Insert(T[i-1], id, 1);
}
rep(i, 1, n+1)
S[i] = T[0];

int ans, lid, rid;

rep(i, 0, q) {
if (Q[i].op) {
lid = lower_bound(b, b+m, a[Q[i].l]) - b;
rid = lower_bound(b, b+m, Q[i].k) - b;
add(Q[i].l, lid, -1);
add(Q[i].l, rid, 1);
a[Q[i].l] = Q[i].k;
} else {
int id = Query(Q[i].l, Q[i].r, Q[i].k);
ans = b[id];
printf("%d\n", ans);
}
}
}

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

int t;
char op[4];

scanf("%d", &t);
while (t--) {
scanf("%d %d", &n, &q);
init();
rep(i, 1, n+1) {
scanf("%d", &a[i]);
b[m++] = a[i];
}
rep(i, 0, q) {
scanf("%s", op);
if (op[0] == 'Q') {
Q[i].op = 0;
scanf("%d %d %d", &Q[i].l, &Q[i].r, &Q[i].k);
} else {
Q[i].op = 1;
scanf("%d %d", &Q[i].l, &Q[i].k);
b[m++] = Q[i].k;
}
}

solve();
}

#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 = 20
bound = 10**4
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):
op = randint(0, 1)
if op:
l = randint(1, n)
r = randint(l, n)
k = randint(1, r-l+1)
fout.write("Q %d %d %d\n" % (l, r, k))
else:
l = randint(1, n)
k = randint(1, bound)
fout.write("C %d %d\n" % (l, k))

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

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