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

SPOJ QTREE5 Query on a tree V(边分治)

2016-03-31 23:31 561 查看
和QTREE4的差不多

#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

using namespace std;

#pragma comment(linxer, "/STACK:102400000,102400000")
#define LL long long
#define pii pair<int, int>
#define MP make_pair
#define ls i << 1
#define rs ls | 1
#define md (ll + rr >> 1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define mod 1000000007
#define inf 0x3f3f3f3f
#define N 200010
#define M 4000020

int fst
, vv[M], nxt[M], cost[M], e;
int f
, rt, edg, C
;
int sz
, tim, tot, mx
;
int col
, fa
, lc
, rc
;
int x
, cx;
bool vis[M];
priority_queue<int> q1
, q2
;

void init(){
memset(fst, -1, sizeof fst); e = 0;
memset(f, -1, sizeof f);
}
void _add(int u, int v, int c){
vv[e] = v, nxt[e] = fst[u], cost[e] = c, fst[u] = e++;
}
void add(int u, int v, int c){
vv[e] = v, nxt[e] = f[u], cost[e] = c, f[u] = e++;
}

void dfsS(int u, int p){
sz[u] = 1;
for(int i = fst[u]; ~i; i = nxt[i]){
int v = vv[i];
if(v == p || vis[i]) continue;
dfsS(v, u);
sz[u] += sz[v];
}
}
void dfsE(int u, int p, int d){
add(u, tim, d);
x[cx++] = d;
for(int i = fst[u]; ~i; i = nxt[i]){
int v = vv[i], c = cost[i];
if(v == p || vis[i]) continue;
mx[v] = max(sz[v], tot - sz[v]);
if(rt == -1 || mx[v] < mx[rt])
rt = v, edg = i, C[tim] = c;
dfsE(v, u, d + c);
}
}
pii find_edge(int u){
dfsS(u, -1);
tot = sz[u], rt = -1, edg = -1, cx = 0;
dfsE(u, -1, 0);
//for(int i = 0; i < cx; ++i)
//  q2[tim].push(x[i]);
return MP(rt, edg);
}
void solve(int u){
++tim;
pii ee = find_edge(u);
if(ee.first == -1){
return ;
}
int i = ee.second, u1 = vv[i], u2 = vv[i^1];
vis[i] = vis[i^1] = 1;
int cur = tim;
lc[cur] = tim + 1;
fa[tim+1] = cur;
solve(u1);
rc[cur] = tim + 1;
fa[tim+1] = cur;
solve(u2);
}

int top(int k){
while(1){
if(q1[k].empty()) return -inf;
if(q2[k].empty()) return q1[k].top();
if(q1[k].top() == q2[k].top())
q1[k].pop(), q2[k].pop();
else return q1[k].top();
}
}
void gao(int u){
for(int i = f[u]; ~i; i = nxt[i]){
int v = vv[i], d = cost[i];
if(col[u]) q1[v].push(d);
else q2[v].push(d);
}
}
int find(int u, int son){
for(int i = f[u]; ~i; i = nxt[i]){
int v = vv[i], d = cost[i];
if(v == son){
//  printf("%d\n", d);
return d;
}
}
return -inf;
}
void query(int u){
int ans = -inf;
for(int i = f[u]; ~i; i = nxt[i]){
int v = vv[i], d = cost[i];
/*
if(lc[v] && rc[v]){
printf("%d %d %d %d %d\n",v, lc[v], rc[v], top(lc[v]), top(rc[v]));
ans = max(ans, top(rc[v]) + C[v] + find(u, lc[v]));
ans = max(ans, top(lc[v]) + C[v] + find(u, rc[v]));
}
*/
if(fa[v]){
int son  = lc[fa[v]] == v ? rc[fa[v]] : lc[fa[v]];
ans = max(ans, top(son) - 1 + d);
}
}
printf("%d\n", -ans);
}
int main(){
int n;
scanf("%d", &n);
init();
for(int i = 1; i < n; ++i){
int u, v;
scanf("%d%d", &u, &v);
_add(u, v, -1);
_add(v, u, -1);
}
tim = 0;
solve(1);
int q, white = 0;
scanf("%d", &q);
while(q--){
int op, u;
scanf("%d%d", &op, &u);
if(op == 0){
col[u] ^= 1;
if(col[u]) white++;
else white--;
gao(u);
}
else{
if(white == 0)
puts("-1");
else if(col[u])
puts("0");
else
query(u);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: