链接 poj_3321
dfs序加树状数组维护子树和
code
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e5 + 10;
int h[N], ne[N<<1], e[N<<1], w[N<<1], idx;
int in[N], out[N];
int a[N], c[N];
int time = 0;
int n, m;
//int num[N]; 记录dfs时每个节点顺序
//int id[N];记录dfs序
//int cnt = 0;
void dfs(int now, int fa)
{
in[now] = ++ time;
//num[time] = now;
//id[cnt ++] = now;
for(int i = h[now]; ~i; i = ne[i])
{
int j = e[i];
if(j != fa)
{
dfs(j, now);
//id[cnt ++] = now;
}
}
out[now] = time;
}
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
}
int lowbit(int x)
{
return x & -x;
}
int sum(int x)
{
int res = 0;
for(int i = x; i > 0; i -= lowbit(i))
{
res += c[i];
}
return res;
}
int query(int x)
{
int l = in[x];
int r = out[x];
return sum(r) - sum(l-1);
}
void change(int y)
{
int x = in[y];
if(a[x])
{
a[x] = 0;
for(int i = x; i <= n; i += lowbit(i))
{
c[i] -= 1;
}
}
else
{
a[x] = 1;
for(int i = x; i <= n; i += lowbit(i))
{
c[i] += 1;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while(cin >> n)
{
idx = 0;
time = 0;
memset(h, -1, sizeof(h));
for(int i = 0; i < n - 1; i ++)
{
int a, b;
cin >> a >> b;
add(a, b);
}
dfs(1, -1);
for(int i = 1; i <= n; i ++)
{
a[i] = 1;
for(int j = i; j <= n; j += lowbit(j))
{
c[j] += 1;
}
}
cin >> m;
while(m --)
{
char c;
int x;
cin >> c >> x;
if(c == 'Q')
{
printf("%d\n", query(x));
}
else
{
change(x);
}
}
}
return 0;
}
欧拉序加ST表求lca
lca模板题
code
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 5e5 + 5;
int h[N], e[N<<1], ne[N<<1], idx;
int order[N<<1], depth[N<<1], cnt;
int st[N<<1][20];
int start[N];
int lg[N<<1];
int n, m, s;
void dfs(int u, int fa)
{
start[u] = ++ cnt;
order[cnt] = u;
depth[cnt] = fa + 1;
for(int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
if(start[j]) continue;
dfs(j, fa + 1);
order[++cnt] = u;
depth[cnt] = fa + 1;
}
}
void st_init()
{
for(int i = 1; i <= cnt; i ++)
{
st[i][0] = i;
}
int a, b;
for(int j = 1; j <= lg[cnt]; j ++)
{
for(int i = 1; i + (1 << j) - 1 <= cnt; i ++)
{
a = st[i][j-1];
b = st[i+(1<<(j-1))][j-1];
if(depth[a] < depth[b])
st[i][j] = a;
else
st[i][j] = b;
}
}
}
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
memset(h, -1, sizeof(h));
cin >> n >> m >> s;
int x, y;
for(int i = 0; i < n-1; i ++)
{
cin >> x >> y;
add(x, y);
add(y, x);
}
dfs(s, 0);
lg[0] = -1;//初始化对数
for(int i = 1; i <= cnt; i ++)
{
lg[i] = lg[i>>1] + 1;
}
st_init();
while(m --)
{
cin >> x >> y;
x = start[x];
y = start[y];
if(x > y) swap(x, y);
int k = (y - x) + 1;
k = lg[k];
int a, b;
a = st[x][k];
b = st[y - (1 << k) + 1][k];
if(depth[a] < depth[b])
{
cout << order[a] << endl;
}
else
{
cout << order[b] << endl;
}
}
//4 1 5 1 3 1 4 2 4
//1 2 3 2 3 2 1 2 1
//2 8 5 1 3
return 0;
}