QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#419947 | #8716. 树 | BYR_KKK | WA | 0ms | 14476kb | C++14 | 2.2kb | 2024-05-24 12:59:11 | 2024-05-24 12:59:11 |
Judging History
answer
#include<bits/stdc++.h>
#define int long long
const int maxn=2e5+10;
std::vector<int>a[maxn];
int b[maxn],n,m,q,pow2[60],lg[maxn],st[maxn][60],fa[maxn],dep[maxn];
namespace lca{
void dfs(int now,int fat){
dep[now]=dep[fat]+1;
fa[now]=fat;
for(int i:a[now]){
if(i==fat) continue;
dfs(i,now);
}
}
void pre(){
//处理出 st[i][j] 代表 i 在树上不算自己跳 2^j 个点到哪
for(int i=1;i<=n;i++) st[i][0]=fa[i];
for(int i=1;i<=lg[n]+1;i++)
for(int j=1;j<=n;j++) st[j][i]=st[st[j][i-1]][i-1];
}
int query(int x,int y){
if(dep[x]<dep[y]) std::swap(x,y);
//始终让 x 是深度更大的那个点
//应该先让他们跳到同一深度
for(int j=59;j>=0;j--){
if(dep[st[y][j]]<dep[x]) continue;
y=st[y][j];
}
if(x==y) return x;
//想让他们同时往上跳
for(int j=59;j>=0;j--){
if(st[x][j]==st[y][j]) continue;
x=st[x][j],y=st[y][j];
}
return fa[x];
}
int dis(int x,int y){
if(dep[x]<dep[y]) std::swap(x,y);
int l=query(x,y);
return dep[x]+dep[y]-2*dep[l];
}
}
int getans(int x,int y,int z){
return (lca::dis(x,y)+lca::dis(y,z)==lca::dis(x,z))?(0):(1);
}
signed main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cin>>n>>m>>q;
pow2[0]=1;
for(int i=1;i<60;i++) pow2[i]=pow2[i-1]*2;
lg[0]=-1;
for(int i=1;i<=n;i++) lg[i]=lg[i>>1]+1;
for(int i=1;i<n;i++){
int u,v;
std::cin>>u>>v;
a[u].push_back(v);
a[v].push_back(u);
}
for(int i=1;i<=m;i++) std::cin>>b[i];
lca::dfs(1,1);
lca::pre();
int ans=1;
//如果要在 a[x] 处不设景点
//当且仅当 a[x-1] -> a[x+1] 会经过 x
//即 a[x-1] -> lca(a[x-1],a[x+1]) -> a[x+1] 会经过 x
//这个条件满足当且仅当 dis[a[x]][a[x-1]]+dis[a[x]][a[x+1]]==dis[a[x-1]][a[x+1]]
//显然, a[1] 和 a[n] 是必须设景点的
for(int i=2;i<n;i++) ans+=getans(b[i-1],b[i],b[i+1]);
while(q--){
int p,w;
std::cin>>p>>w;
for(int i=p-1;i<=p+1;i++){
if(i<1||i>n) continue;
if(i-1<1||i+1>n) continue;
ans-=getans(b[i-1],b[i],b[i+1]);
}
b[p]=w;
for(int i=p-1;i<=p+1;i++){
if(i<1||i>n||i-1<1||i+1>n) continue;
ans+=getans(b[i-1],b[i],b[i+1]);
}
std::cout<<ans<<'\n';
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 14476kb
input:
5 5 3 2 1 3 2 1 4 5 1 1 5 4 2 3 1 3 5 3 3 3
output:
4 4 4
result:
wrong answer 3rd numbers differ - expected: '5', found: '4'