# bzoj3307 雨天的尾巴

【题解】

bzoj上恰好10s。。

# pragma comment(linker, /STACK:102400000,102400000)
# include <queue>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 2e5 + 10, N = 6e6 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

namespace SMT {
int p[N], w[N], ch[N][2], siz;

inline void up(int x) {
if(w[ch[x][0]] >= w[ch[x][1]]) {
w[x] = w[ch[x][0]];
p[x] = p[ch[x][0]];
} else {
w[x] = w[ch[x][1]];
p[x] = p[ch[x][1]];
}
}

inline void edt(int &x, int l, int r, int pos, int d) {
if(!x) x = ++siz;
if(l == r) {
p[x] = l;
w[x] += d;
return ;
}
int mid = l+r>>1;
if(pos <= mid) edt(ch[x][0], l, mid, pos, d);
else edt(ch[x][1], mid+1, r, pos, d);
up(x);
}

inline int merge(int x, int y, int l, int r) {
if(!x || !y) return x+y;
if(l == r) {
w[x] = w[x] + w[y];
return x;
}
int mid = l+r>>1;
ch[x][0] = merge(ch[x][0], ch[y][0], l, mid);
ch[x][1] = merge(ch[x][1], ch[y][1], mid+1, r);
up(x);
return x;
}
}

int head[M], nxt[M], to[M], tot=0;
inline void add(int u, int v) {
++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
}
inline void adde(int u, int v) {
}

int n, m, rt[M];
int fa[M][17], dep[M];
inline void dfs(int x, int father) {
dep[x] = dep[father] + 1;
fa[x][0] = father;
for (int i=1; i<=16; ++i) fa[x][i] = fa[fa[x][i-1]][i-1];
for (int i=head[x]; i; i=nxt[i]) {
if(to[i] == father) continue;
dfs(to[i], x);
}
}

inline int lca(int u, int v) {
if(dep[u] < dep[v]) swap(u, v);
for (int i=16; ~i; --i)
if((dep[u]-dep[v]) & (1<<i)) u = fa[u][i];
if(u == v) return u;
for (int i=16; ~i; --i)
if(fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
return fa[u][0];
}

int ans[M];

inline void gans(int x) {
for (int i=head[x]; i; i=nxt[i]) {
if(to[i] == fa[x][0]) continue;
gans(to[i]);
rt[x] = SMT::merge(rt[x], rt[to[i]], 1, 1e9);
}
ans[x] = SMT::p[rt[x]];
}

int main() {
//    freopen("3307.in", "r", stdin);
//    freopen("3307.out", "w", stdout);
cin >> n >> m;
for (int i=1, u, v; i<n; ++i) {
scanf("%d%d", &u, &v);
}
dfs(1, 0);
for (int i=1, u, v, z; i<=m; ++i) {
scanf("%d%d%d", &u, &v, &z);
int LCA = lca(u, v);
SMT::edt(rt[u], 1, 1e9, z, 1);
SMT::edt(rt[v], 1, 1e9, z, 1);
SMT::edt(rt[LCA], 1, 1e9, z, -1);
if(LCA != 1) SMT::edt(rt[fa[LCA][0]], 1, 1e9, z, -1);
}

gans(1);
for (int i=1; i<=n; ++i) printf("%d\n", ans[i]);

return 0;
}
View Code

# include <queue>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 2e5 + 10, N = 6e6 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

namespace SMT {
int p[N], w[N], ch[N][2], siz;

inline void up(int x) {
if(w[ch[x][0]] >= w[ch[x][1]]) {
w[x] = w[ch[x][0]];
p[x] = p[ch[x][0]];
} else {
w[x] = w[ch[x][1]];
p[x] = p[ch[x][1]];
}
}

inline void edt(int &x, int l, int r, int pos, int d) {
if(!x) x = ++siz;
if(l == r) {
w[x] += d;
if(w[x] <= 0) p[x] = 0;
else p[x] = l;
return ;
}
int mid = l+r>>1;
if(pos <= mid) edt(ch[x][0], l, mid, pos, d);
else edt(ch[x][1], mid+1, r, pos, d);
up(x);
}

inline int merge(int x, int y, int l, int r) {
if(!x || !y) return x+y;
if(l == r) {
w[x] = w[x] + w[y];
if(w[x] <= 0) p[x] = 0;
else p[x] = l;
return x;
}
int mid = l+r>>1;
ch[x][0] = merge(ch[x][0], ch[y][0], l, mid);
ch[x][1] = merge(ch[x][1], ch[y][1], mid+1, r);
up(x);
return x;
}

inline void prt(int x, int l, int r) {
if(!x) return ;
printf("%d %d %d %d %d\n", x, l, r, p[x], w[x]);
if(l == r) return;
int mid = l+r>>1;
prt(ch[x][0], l, mid);
prt(ch[x][1], mid+1, r);
}
}

int head[M], nxt[M], to[M], tot=0;
inline void add(int u, int v) {
++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
}
inline void adde(int u, int v) {
}

int n, m, rt[M];
int fa[M][17], dep[M];
bool vis[M];
queue<int> q;
inline void bfs(int x) {
q.push(x); dep[x] = 1;
while(!q.empty()) {
int top = q.front(); q.pop(); vis[top] = 1;
for (int i=1; i<=16; ++i) fa[top][i] = fa[fa[top][i-1]][i-1];
for (int i=head[top]; i; i=nxt[i]) {
if(!vis[to[i]]) {
fa[to[i]][0] = top;
dep[to[i]] = dep[top] + 1;
q.push(to[i]);
}
}
}
}

inline int lca(int u, int v) {
if(dep[u] < dep[v]) swap(u, v);
for (int i=16; ~i; --i)
if((dep[u]-dep[v]) & (1<<i)) u = fa[u][i];
if(u == v) return u;
for (int i=16; ~i; --i)
if(fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
return fa[u][0];
}

int ans[M];
int st[M], cur[M], stn=0;
inline void gans(int start) {
int x, t;
st[++stn] = start;
while(stn) {
x = st[stn];
if(to[cur[x]] == fa[x][0]) cur[x] = nxt[cur[x]];
if(!cur[x]) {
--stn;
ans[x] = SMT::p[rt[x]];
//            printf("==================%d=================\n", x);
//            SMT::prt(rt[x], 1, 1e9);
t = fa[x][0];
if(t) rt[t] = SMT::merge(rt[t], rt[x], 1, 1e9);
} else {
t = to[cur[x]];
st[++stn] = t;
cur[x] = nxt[cur[x]];
}
}
}

int main() {
//    freopen("3307.in", "r", stdin);
//    freopen("3307.out", "w", stdout);
cin >> n >> m;
for (int i=1, u, v; i<n; ++i) {
scanf("%d%d", &u, &v);
}
bfs(1);
for (int i=1, u, v, z; i<=m; ++i) {
scanf("%d%d%d", &u, &v, &z);
int LCA = lca(u, v);
SMT::edt(rt[u], 1, 1e9, z, 1);
SMT::edt(rt[v], 1, 1e9, z, 1);
SMT::edt(rt[LCA], 1, 1e9, z, -1);
if(LCA != 1) SMT::edt(rt[fa[LCA][0]], 1, 1e9, z, -1);
}

for (int i=1; i<=n; ++i) cur[i] = head[i];
gans(1);
for (int i=1; i<=n; ++i) printf("%d\n", ans[i]);

return 0;
}
/*
5 5
1 2
2 3
3 4
4 5
1 2 1
2 3 1
1 3 1
1 4 2
3 4 2
*/
View Code

posted @ 2017-06-10 21:23  Galaxies  阅读(224)  评论(0编辑  收藏  举报