您的位置:首页 > 产品设计 > UI/UE

【HDOJ】3726 Graph and Queries

2015-10-20 11:27 399 查看
Treap的基础题目,Treap是个挺不错的数据结构。

/*  */
#include <iostream>
#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 {
char c;
int x, y;
} Cmd;

typedef struct Node {
Node* ch[2];
int r, v, s;

Node() {}

Node(int v_) {
ch[0] = ch[1] = NULL;
r = rand();
v = v_;
s = 1;
}

friend bool operator<(const Node& a, const Node& b) {
return a.r < b.r;
}

int cmp(int x) const {
if (x == v)    return -1;
return x<v ? 0:1;
}

void maintain() {
s = 1;
if (ch[0] != NULL)    s += ch[0]->s;
if (ch[1] != NULL)    s += ch[1]->s;
}

} Node;

void rotate(Node*& o, int d) {
Node* k = o->ch[d^1];
o->ch[d^1] = k->ch[d];
k->ch[d] = o;
o->maintain();
k->maintain();
o = k;
}

void insert(Node*& o, int x) {
if (o == NULL) {
o = new Node(x);
} else {
int d = x<o->v ? 0:1;
insert(o->ch[d], x);
if (o->ch[d]->r > o->r)
rotate(o, d^1);
}
o->maintain();
}

void remove(Node*& o, int x) {
int d = o->cmp(x);

if (d == -1) {
Node* u = o;
if (o->ch[0]!=NULL && o->ch[1]!=NULL) {
int d2 = o->ch[0]->r > o->ch[1]->r ? 1:0;
rotate(o, d2);
remove(o->ch[d2], x);
} else {
if (o->ch[0] == NULL)
o = o->ch[1];
else
o = o->ch[0];
delete u;
}
} else {
remove(o->ch[d], x);
}
if (o != NULL)
o->maintain();
}

const int maxc = 5e5+5;
const int maxn = 2e4+5;
const int maxm = 6e4+5;
Cmd cmd[maxc];
Node* rt[maxn];
int W[maxn], pre[maxn];
int U[maxm], V[maxm];
bool mark[maxm];

int find(int x) {
if (x == pre[x])
return x;
return pre[x] = find(pre[x]);
}

void removetree(Node*& x) {
if (x->ch[0] != NULL)    removetree(x->ch[0]);
if (x->ch[1] != NULL)    removetree(x->ch[1]);
delete x;
x = NULL;
}

void mergeto(Node*& src, Node*& des) {
if (src->ch[0] != NULL)    mergeto(src->ch[0], des);
if (src->ch[1] != NULL)    mergeto(src->ch[1], des);
insert(des, src->v);
delete src;
src = NULL;
}

void addEdge(int k) {
int u = U[k], v = V[k];
int fu = find(u), fv = find(v);

if (fu != fv) {
if (rt[fu]->s < rt[fv]->s) {
pre[fu] = fv;
mergeto(rt[fu], rt[fv]);
} else {
pre[fv] = fu;
mergeto(rt[fv], rt[fu]);
}
}
}

int kth(Node* o, int k) {
if (o==NULL || k<=0 || k>o->s)
return 0;

int s = o->ch[1]==NULL ? 0:o->ch[1]->s;
if (k == s+1)
return o->v;
else if (k <= s)
return kth(o->ch[1], k);
else
return kth(o->ch[0], k-s-1);
}

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

int tt = 0;
int n, m, nc;
int x, y;
char s[3];
__int64 tot, ans;

while (scanf("%d %d",&n,&m)!=EOF && (n||m)) {
rep(i, 1, n+1)
scanf("%d", &W[i]);
rep(i, 1, m+1)
scanf("%d %d", &U[i], &V[i]);

memset(mark, false, sizeof(mark));
nc = 0;
while (scanf("%s", s)!=EOF && s[0]!='E') {
cmd[nc].c = s[0];
if (s[0] == 'D') {
scanf("%d", &x);
cmd[nc].x = x;
mark[x] = true;
} else if (s[0] == 'Q') {
scanf("%d %d", &x, &y);
cmd[nc].x = x;
cmd[nc].y = y;
} else if (s[0] == 'C') {
scanf("%d %d", &x, &y);
cmd[nc].x = x;
cmd[nc].y = W[x];
W[x] = y;
}
++nc;
}

rep(i, 1, n+1) {
pre[i] = i;
if (rt[i] != NULL)
removetree(rt[i]);
rt[i] = new Node(W[i]);
}

rep(i, 1, m+1) {
if (!mark[i])
addEdge(i);
}

ans = tot = 0;
per(i, 0, nc) {
if (cmd[i].c == 'D') {
addEdge(cmd[i].x);
} else if (cmd[i].c == 'Q') {
int fx = find(cmd[i].x);
++tot;
ans += kth(rt[fx], cmd[i].y);
} else if (cmd[i].c == 'C') {
int fx = find(cmd[i].x);
remove(rt[fx], W[cmd[i].x]);
insert(rt[fx], cmd[i].y);
W[cmd[i].x] = cmd[i].y;
}
}
printf("Case %d: %.06lf\n", ++tt, 1.0*ans/tot);
}

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

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