# 题目描述

• $$\forall i \in (1,m]$$$$a_i$$$$a_{i−1}$$的祖先或 $$a_{i−1}$$$$ai$$的祖先
• $$\forall 1 \leq i \lt j \leq m, a_i \neq a_j$$

# 输出格式

$$T$$ 行，每行一个整数表示每组数据的答案。

# 样例

## 输入样例1

18
5 3
1 5
4 5
2 5
1 6
8 7
7 6


## 输出样例1

7


# 正解

$f_x=f_A+f_B+1$

# 比较正常的代码

#include <bits/stdc++.h>
using namespace std;
struct node {
int nxt, to;
} a[200005];
struct tree {
int l, r, mx, mpos;
} tr[400005];
int t, n, h[100005], tot, x, y, f[100005], ans, num[100005], num2[100005], sz[100005], cnt;
void build(int pos, int l, int r) {
tr[pos].l = l, tr[pos].r = r;
if (l == r) {
tr[pos].mpos = l;
return;
}
int mid = (l + r) / 2;
build(pos * 2, l, mid);
build(pos * 2 + 1, mid + 1, r);
tr[pos].mpos = l;
}
void update(int pos, int x, int y) {
if (x < tr[pos].l || tr[pos].r < x)
return;
if (tr[pos].l == tr[pos].r && tr[pos].l == x) {
tr[pos].mx = y;
return;
}
update(pos * 2, x, y);
update(pos * 2 + 1, x, y);
if (tr[pos * 2].mx > tr[pos * 2 + 1].mx) {
tr[pos].mx = tr[pos * 2].mx;
tr[pos].mpos = tr[pos * 2].mpos;
} else {
tr[pos].mx = tr[pos * 2 + 1].mx;
tr[pos].mpos = tr[pos * 2 + 1].mpos;
}
}
int query(int pos, int l, int r) {
if (r < tr[pos].l || tr[pos].r < l)
return 0;
if (l <= tr[pos].l && tr[pos].r <= r) {
return tr[pos].mpos;
}
int lm = query(pos * 2, l, r), rm = query(pos * 2 + 1, l, r);
if (f[num2[lm]] > f[num2[rm]])
return lm;
else
return rm;
}
void add(int x, int y) {
tot++;
a[tot].to = y;
a[tot].nxt = h[x];
h[x] = tot;
}
void dfs(int x, int fa) {
num[x] = ++cnt, num2[cnt] = x;
for (int i = h[x]; i; i = a[i].nxt) {
if (a[i].to == fa)
continue;
dfs(a[i].to, x);
sz[x] += sz[a[i].to];
}
sz[x]++;
}
void dfs2(int x, int fa) {
for (int i = h[x]; i; i = a[i].nxt) {
if (a[i].to == fa)
continue;
dfs2(a[i].to, x);
}
int mx = 0, sum = 0;
for (int i = 1; i <= 2; i++) {
mx = query(1, num[x], num[x] + sz[x] - 1);
if (num2[mx] != x && f[num2[mx]] != 0) {
sum += f[num2[mx]];
f[num2[mx]] = 0;
update(1, mx, 0);
}
}
f[x] = 1 + sum, ans = max(ans, f[x]);
update(1, num[x], f[x]);
}
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
memset(h, 0, sizeof(h));
memset(a, 0, sizeof(a));
memset(f, 0, sizeof(f));
memset(tr, 0, sizeof(tr));
memset(sz, 0, sizeof(sz));
tot = 0, ans = 0, cnt = 0;
for (int i = 1; i <= n - 1; i++) {
scanf("%d%d", &x, &y);
}
build(1, 1, n), dfs(1, 0), dfs2(1, 0);
printf("%d\n", ans);
}
}


# 考场代码

#include<bits/stdc++.h>
using namespace std;
struct node
{
long long nxt,to;
}a[200005];
struct tree
{
long long l,r,mx,mpos;
}tr[1000005];
long long t,n,h[100005],tot,x,y,f[100005],ans,vis[100005],num[100005],num2[100005],sz[100005],cnt;
stack<pair<long long,long long> >s;
void build(long long pos,long long l,long long r)
{
tr[pos].l=l,tr[pos].r=r;
if(l==r)
{
tr[pos].mpos=l;
return;
}
long long mid=(l+r)/2;
build(pos*2,l,mid);
build(pos*2+1,mid+1,r);
tr[pos].mpos=l;
}
void update(long long pos,long long x,long long y)
{
if(x<tr[pos].l||tr[pos].r<x)return;
if(tr[pos].l==tr[pos].r&&tr[pos].l==x)
{
tr[pos].mx=y;
return;
}
update(pos*2,x,y);
update(pos*2+1,x,y);
if(tr[pos*2].mx>tr[pos*2+1].mx)
{
tr[pos].mx=tr[pos*2].mx;
tr[pos].mpos=tr[pos*2].mpos;
}
else
{
tr[pos].mx=tr[pos*2+1].mx;
tr[pos].mpos=tr[pos*2+1].mpos;
}
}
long long query(long long pos,long long l,long long r)
{
if(r<tr[pos].l||tr[pos].r<l)return 0;
if(l<=tr[pos].l&&tr[pos].r<=r)
{
return tr[pos].mpos;
}
long long lm=query(pos*2,l,r),rm=query(pos*2+1,l,r);
if(f[num2[lm]]>f[num2[rm]])return lm;
else return rm;
}
void add(long long x,long long y)
{
tot++;
a[tot].to=y;
a[tot].nxt=h[x];
h[x]=tot;
}
int main()
{
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
memset(h,0,sizeof(h));
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
memset(vis,0,sizeof(vis));
memset(tr,0,sizeof(tr));
memset(sz,0,sizeof(sz));
memset(num,0,sizeof(num));
memset(num2,0,sizeof(num2));
while(!s.empty())s.pop();
tot=0,ans=0,cnt=0;
for(int i=1;i<=n-1;i++)
{
scanf("%lld%lld",&x,&y);
}
s.push({1,0});
while(!s.empty())
{
long long x=s.top().first,fa=s.top().second;
if(num[x]==0)num[x]=++cnt,num2[cnt]=x;
for(int i=h[x];i;i=a[i].nxt)
{
if(a[i].to==fa)continue;
if(!vis[a[i].to])s.push({a[i].to,x});
}
if(s.top().first==x)
{
for(int i=h[x];i;i=a[i].nxt)
{
if(a[i].to==fa)continue;
sz[x]+=sz[a[i].to];
}
sz[x]++,vis[x]=1;
s.pop();
}
}
memset(vis,0,sizeof(vis));
build(1,1,n);
s.push({1,0});
while(!s.empty())
{
long long x=s.top().first,fa=s.top().second;
for(int i=h[x];i;i=a[i].nxt)
{
if(a[i].to==fa)continue;
if(!vis[a[i].to])s.push({a[i].to,x});
}
if(s.top().first==x)
{
long long mx=0,sum=0;
for(int i=1;i<=2;i++)
{
mx=query(1,num[x],num[x]+sz[x]-1);
if(num2[mx]!=x&&f[num2[mx]]!=0)
{
sum+=f[num2[mx]];
f[num2[mx]]=0;
update(1,mx,0);
}
}
f[x]=1+sum;
ans=max(ans,f[x]);
update(1,num[x],f[x]);
vis[x]=1,s.pop();
}
}
printf("%lld\n",ans);
}
}

posted @ 2023-04-25 18:03  DengDuck  阅读(60)  评论(0编辑  收藏  举报