您现在的位置是:主页 > news > 查答案的网站制作模板/seo是什么的简称

查答案的网站制作模板/seo是什么的简称

admin2025/5/11 11:51:00news

简介查答案的网站制作模板,seo是什么的简称,建设银行网站维护,网站建设代理费用Description 在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下两种操作:1. 标记操作:对某个结点打上标记(在最开始&…

查答案的网站制作模板,seo是什么的简称,建设银行网站维护,网站建设代理费用Description 在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下两种操作:1. 标记操作:对某个结点打上标记(在最开始&…

Description

在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下
两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个
结点,可以打多次标记。)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖
先)你能帮帮他吗?

Solution

还是非常巧妙的思维

离线,先记录每个点的标记数,倒序处理询问,遇到打标记就把标记数减一,对于标记数为0的点就用并查集与它的父节点合并

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<vector>
#define MAXN 100005
using namespace std;
int n,q,head[MAXN],cnt=0,f[MAXN],father[MAXN],num[MAXN],sign[MAXN];
char opt[MAXN];
vector<int>v;
struct Node
{int next,to;
}Edges[MAXN*2];
void addedge(int u,int v)
{Edges[++cnt].next=head[u];head[u]=cnt;Edges[cnt].to=v;
}
int read()
{int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
int find(int x)
{if(father[x]==x)return x;return father[x]=find(father[x]);
}
void dfs(int u)
{if(!sign[u])father[u]=find(f[u]); for(int i=head[u];~i;i=Edges[i].next){int v=Edges[i].to;if(v==f[u])continue;f[v]=u;dfs(v);}
}
int main()
{memset(head,-1,sizeof(head));n=read(),q=read();for(int i=1;i<n;i++){int u=read(),v=read();addedge(u,v);addedge(v,u);father[i]=i;}father[n]=n,sign[1]++;for(int i=1;i<=q;i++){opt[i]=getchar();while(opt[i]!='Q'&&opt[i]!='C')opt[i]=getchar();num[i]=read();if(opt[i]=='C')sign[num[i]]++;}dfs(1);for(int i=q;i>0;i--){if(opt[i]=='C'){sign[num[i]]--;if(!sign[num[i]])father[num[i]]=find(f[num[i]]);}elsev.push_back(find(num[i]));}for(int i=v.size()-1;i>=0;i--)printf("%d\n",v[i]);return 0;
} 

 

转载于:https://www.cnblogs.com/Zars19/p/6872287.html