您的位置:首页 > 其它

BZOJ3570 DZY Loves Physics I

2014-11-16 20:12 405 查看
就是给一个数列,维护操作:(1)加一个数(2)求当前全部数的第K大。。。

看了Claris大爷的做法深有启发,于是本蒟蒻的替罪羊树的第一次就没了。。。

写完才发现。。。Orz主席树怎么忘了、、、貌似实现更简单啊!!!

不管了QAQ

/**************************************************************
Problem: 3570
User: rausen
Language: C++
Result: Accepted
Time:2284 ms
Memory:6288 kb
****************************************************************/

#include <cstdio>
#include <cmath>

using namespace std;
typedef long long ll;
typedef double lf;
const lf A = 0.8;
const int N = 200005;

int n, C;
int size
, son
[2], val
, f
, tot, root;
int data
, id
, cnt;

inline int read() {
int x = 0;
char ch = getchar();
while (ch < '0' || '9' < ch)
ch = getchar();
while ('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x;
}

int ins(int x, int p) {
++size[x];
int S = p >= val[x];
if (!son[x][S]) {
son[x][S] = ++tot;
f[tot] = x, size[tot] = 1, val[tot] = p;
return tot;
}else return ins(son[x][S], p);
}

int build(int fa, int l, int r) {
int mid = l + r >> 1, x = id[mid];
f[x] = fa, son[x][0] = son[x][1] = 0, size[x] = 1;
val[x] = data[mid];
if (l == r) return x;
if (l < mid) size[x] += size[son[x][0] = build(x, l, mid - 1)];
if (mid < r) size[x] += size[son[x][1] = build(x, mid + 1, r)];
return x;
}

void dfs(int x) {
if (son[x][0]) dfs(son[x][0]);
data[++cnt] = val[x], id[cnt] = x;
if (son[x][1]) dfs(son[x][1]);
}

inline int rebuild(int x) {
cnt = 0;
dfs(x);
return build(f[x], 1, cnt);
}

inline void insert(int p) {
if (!root) {
root = tot = size[1] = 1;
val[1] = p;
return;
}
int x = ins(root, p), dep = 0, z = x;
while (f[z]) z = f[z], ++dep;
if (dep < log(tot) / log(1 / A)) return;
while ((lf) size[son[x][0]] < A * size[x] && (lf)size[son[x][1]] < A * size[x])
x = f[x];
if (!x) return;
if (x == root) {
root = rebuild(x);
return;
}
int y = f[x], S = son[y][1] == x;
son[y][S] = rebuild(x);
}

inline int find_kth(int k) {
int x = root, sum;
while (1) {
sum = size[son[x][0]] + 1;
if (k == sum) return val[x];
if (k < sum) x = son[x][0];
else k -= sum, x = son[x][1];
}
}

int main() {
int x, y, z;
n = read(), C = read();
while (n--) {
x = read(), read(), read();
insert(x);
}
n = read();
while (n--) {
x = read();
if (x) {
y = read(), z = find_kth(read());
printf("%.3lf\n", sqrt((ll) 2 * C * y + (ll) z * z));
} else
insert(read()), read(), read();
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: