您的位置:首页 > 其它

【HDOJ】4605 Magic Ball Game

2016-02-14 23:34 316 查看
思路1:
树状数组+离线处理,对所有的w离散化处理,边dfs边使用树状数组更新左右w的情况。
思路2:
主席树,边bfs边建树。结点信息存储cnt,然后在线查询。
树状数组。

/* 4605 */
#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 ques_t {
int w, id;

ques_t() {}
ques_t(int w, int id):
w(w), id(id) {}

} ques_t;

const int maxn = 1e5+5;
const int maxm = maxn * 2;
int a[maxm];
int W[maxn];
ques_t Q[maxn];
vector<ques_t> vc[maxn];
int ans[maxn][2];
int son[maxn][2];
int tot[maxm][2];
int n, m;

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

void add(int x, int delta, int id) {
while (x <= m) {
tot[x][id] += delta;
x += lowest(x);
}
}

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

while (x) {
ret += tot[x][id];
x -= lowest(x);
}

return ret;
}

void init() {
memset(son, 0, sizeof(son));
memset(tot, 0, sizeof(tot));
rep(i, 1, n+1)
vc[i].clr();
m = 1;
}

void dfs(int u, int tot) {
int v, sz = SZ(vc[u]);
int llt, lgt, rlt, rgt;
int eq;

rep(i, 0, sz) {
int w = vc[u][i].w;
int id = vc[u][i].id;
llt = sum(w-1, 0);
lgt = sum(m, 0) - sum(w, 0);
rlt = sum(w-1, 1);
rgt = sum(m, 1) - sum(w, 1);
eq = tot - llt - lgt - rlt - rgt;
if (eq) {
ans[id][0] = -1;
} else {
ans[id][0] = (lgt+rgt) + (llt+rlt)*3;
ans[id][1] = rlt;
}
}
if (son[u][0]) {
add(W[u], 1, 0);
dfs(son[u][0], tot+1);
add(W[u], -1, 0);

add(W[u], 1, 1);
dfs(son[u][1], tot+1);
add(W[u], -1, 1);
}
}

void solve() {
int q;
int x, w;

scanf("%d", &q);
rep(i, 0, q) {
scanf("%d %d", &Q[i].id, &Q[i].w);
a[m++] = Q[i].w;
}

sort(a+1, a+m);
m = unique(a+1, a+m) - (a+1);

rep(i, 1, n+1) {
W[i] = lower_bound(a+1, a+1+m, W[i]) - a;
}

rep(i, 0, q) {
int u = Q[i].id;
w = lower_bound(a+1, a+1+m, Q[i].w) - a;
vc[u].pb(ques_t(w, i));
}

dfs(1, 0);

rep(i, 0, q) {
if (ans[i][0] == -1)
puts("0");
else
printf("%d %d\n", ans[i][1], ans[i][0]);
}
}

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

int t;
int u, v1, v2;

scanf("%d", &t);
while (t--) {
init();
scanf("%d", &n);
rep(i, 1, n+1) {
scanf("%d", &W[i]);
a[m++] = W[i];
}
int k;
scanf("%d", &k);
rep(i, 0, k) {
scanf("%d %d %d", &u, &v1, &v2);
son[u][0] = v1;
son[u][1] = v2;
}
solve();
}

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

return 0;
}


主席树。

/* 4605 */
#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 INF = 1e9+5;
const int maxn = 1e5+5;
const int maxm = maxn * 30;
int a[maxn], W[maxn];
int T[maxn];
int lson[maxm], rson[maxm];
int lc[maxm], rc[maxm];
int n, m, tot;
int son[maxn][2];

void init() {
tot = m = 0;
memset(son, 0, sizeof(son));
}

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

lc[rt] = rc[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 p, int lval, int rval) {
int nrt = tot++, ret = nrt;
int l = 0, r = m - 1, mid;

lc[nrt] = lc[rt] + lval;
rc[nrt] = rc[rt] + rval;
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;
}
lc[nrt] = lc[rt] + lval;
rc[nrt] = rc[rt] + rval;
}

return ret;
}

pii Query(int rt, int L, int R, int l, int r) {
if (L==l && R==r)
return mp(lc[rt], rc[rt]);

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

if (R <= mid) {
return Query(lson[rt], L, R, l, mid);
} else if (L > mid) {
return Query(rson[rt], L, R, mid+1, r);
} else {
pii ltmp = Query(lson[rt], L, mid, l, mid);
pii rtmp = Query(rson[rt], mid+1, R, mid+1, r);
return mp(ltmp.fir+rtmp.fir, ltmp.sec+rtmp.sec);
}
}

void solve() {
a[m++] = INF;
a[m++] = 0;
sort(a, a+m);
m = unique(a, a+m) - a;

T[1] = Build(0, m-1);
queue<int> Q;
int u, v;

Q.push(1);
while (!Q.empty()) {
u = Q.front();
Q.pop();
if (son[u][0]) {
int wid = lower_bound(a, a+m, W[u]) - a;
T[son[u][0]] = Insert(T[u], wid, 1, 0);
T[son[u][1]] = Insert(T[u], wid, 0, 1);
Q.push(son[u][0]);
Q.push(son[u][1]);
}
}

int q;
int w;
int n2, n7;

scanf("%d", &q);
while (q--) {
scanf("%d %d", &v, &w);
int wid = lower_bound(a, a+m, w) - a;
if (a[wid] == w) {
// check hit w
pii eq = Query(T[v], wid, wid, 0, m-1);
if (eq.fir+eq.sec > 0) {
puts("0");
continue;
}
}

pii lt = Query(T[v], 0, wid-1, 0, m - 1);
pii gt = Query(T[v], wid, m-1, 0, m - 1);

n2 = (gt.fir+gt.sec) + (lt.fir+lt.sec) * 3;
n7 = lt.sec;

printf("%d %d\n", n7, n2);
}
}

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

int t;
int u;

scanf("%d", &t);
rep(tt, 1, t+1) {
scanf("%d", &n);
init();
rep(i, 1, n+1) {
scanf("%d", &W[i]);
a[m++] = W[i];
}
int k;
scanf("%d", &k);
rep(i, 0, k) {
scanf("%d", &u);
scanf("%d %d", &son[u][0], &son[u][1]);
}
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 = 1
bound = 10**5 / 2
fout.write("%d\n" % (t))
for tt in xrange(t):
m = randint(100, 200)
n = 2 * m + 1
fout.write("%d\n" % (n))
L = []
for i in xrange(n):
w = randint(1, bound)
L.append(w)
fout.write(" ".join(map(str, L)) + "\n")
ust = [1]
vst = range(2, n+1)
fout.write("%d\n" % (m))
for i in xrange(m):
idx = randint(0, len(ust)-1)
u = ust[idx]
ust.remove(u)
V = []
for j in xrange(2):
idx = randint(0, len(vst)-1)
v = vst[idx]
V.append(v)
ust.append(v)
vst.remove(v)
fout.write("%d %d %d\n" % (u, V[0], V[1]))
q = randint(n/2, n)
fout.write("%d\n" % (q))
for i in xrange(q):
x = randint(1, n)
w = randint(1, bound)
fout.write("%d %d\n" % (x, w))

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

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