【bzoj4551】【NOIP2016模拟7.11】树
题目
在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下
两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个
结点,可以打多次标记。)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖
先)你能帮帮他吗?
分析
此题有很多种方法
暴力+并查集
转了别人的
考虑离线处理。
我们将所有的操作倒序处理,利用并查集进行维护。对于一个修改操
作(即失去标记),相当于将这一联通块块与它父亲的联通块合并。对于
一个查询操作,直接查询所在的块的父亲即可。
实现中有些细节需要注意,比如每个点可能会被标记多次,所以要以
最早的被标记时间做为“失去标记”的时间。
时间复杂度为O(n + qα(n))
DFN序+线段树
首先搞一遍dfn序,
接着发现,在用一棵子树中,dfn序都是相邻的。
好了,线段树修改查询。
树链剖分
单独修改、查询1到num的路径。
裸题一枚。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=100005;
using namespace std;
int tree[N*6],top[N],d[N],size[N],deep[N],son[N],fa[N],n,m,tot,ans;
int last[N*2],next[N*2],to[N*2],bef[N],aft[N];
void bj(int x,int y)
{
next[++tot]=last[x];
last[x]=tot;
to[tot]=y;
}
void dg(int x,int y)
{
size[x]=1;
int mx=0;
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=y)
{
deep[j]=deep[x]+1;
fa[j]=x;
dg(j,x);
size[x]+=size[j];
if(size[j]>mx)
{
mx=size[j];
son[x]=j;
}
}
}
}
int dg1(int x,int y)
{
d[++tot]=x;
aft[x]=tot;
bef[tot]=x;
if(!top[x])
top[x]=x;
if(son[x])
{
top[son[x]]=top[x];
dg1(son[x],x);
}
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=y && j!=son[x])
{
dg1(j,x);
}
}
}
int put(int v,int l,int r,int x)
{
if(l==r)
{
tree[v]=bef[x];
return 0;
}
int mid=(l+r)/2;
if(x<=mid)
{
put(v*2,l,mid,x);
}
else
put(v*2+1,mid+1,r,x);
tree[v]=deep[tree[v*2]]>deep[tree[v*2+1]]?tree[v*2]:tree[v*2+1];
}
int find(int v,int l,int r,int x,int y)
{
if(l==x && r==y)
{
ans=deep[ans]>deep[tree[v]]?ans:tree[v];
return 0;
}
int mid=(l+r)/2;
if(y<=mid)
{
find(v*2,l,mid,x,y);
}
else
if(mid<x)
{
find(v*2+1,mid+1,r,x,y);
}
else
{
find(v*2,l,mid,x,mid);
find(v*2+1,mid+1,r,mid+1,y);
}
tree[v]=deep[tree[v*2]]>deep[tree[v*2+1]]?tree[v*2]:tree[v*2+1];
}
int main()
{
freopen("4604.in","r",stdin);
freopen("4604.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
bj(x,y);
bj(y,x);
}
deep[1]=1;
dg(1,0);
top[1]=1;
tot=0;
dg1(1,0);
put(1,1,n,aft[1]);
scanf("\n");
for(int i=1;i<=m;i++)
{
int c;
int x,y;
c=getchar();
while((c!='Q')&&(c!='C'))c=getchar();
scanf("%d\n",&x);
if(c=='C')
{
put(1,1,n,aft[x]);
}
else
{
ans=0;
while(top[x]!=top[1])
{
find(1,1,n,aft[top[x]],aft[x]);
x=fa[top[x]];
}
find(1,1,n,aft[1],aft[x]);
printf("%d\n",ans);
}
}
}
【bzoj4551】【NOIP2016模拟7.11】树的更多相关文章
- NOIP2016模拟赛三 Problem B: 神奇的树
题面 Description 有一棵神奇的树.这棵树有N个节点,在每个节点上都有宝藏,每个宝藏价值V[i]金币:对于每条边,每经过一次都要花费C[i]金币. 值得注意的是,每个宝藏只能领取一次(也可以 ...
- JZOJ 4611. 【NOI2016模拟7.11】接水问题 (贪心+A*+可持久化线段树)
Description: https://gmoj.net/senior/#main/show/4611 题解: 先把A从大到小排序,最小的由排序不等式显然. 考虑类似第k短路的A*的做法. 定义状态 ...
- 「考试」noip模拟9,11,13
9.1 辣鸡 可以把答案分成 每个矩形内部连线 和 矩形之间的连线 两部分 前半部分即为\(2(w-1)(h-1)\),后半部分可以模拟求(就是讨论四种相邻的情况) 如果\(n^2\)选择暴力模拟是有 ...
- vue 模拟下拉树
// 使用vue 做表格部分其他部分暂不修改 var app = new Vue({ el: "#freightTbl", watch: { //监听表格数据的变化[使用 watc ...
- [转载]如何在C++03中模拟C++11的右值引用std::move特性
本文摘自: http://adamcavendish.is-programmer.com/posts/38190.htm 引言 众所周知,C++11 的新特性中有一个非常重要的特性,那就是 rvalu ...
- 串门赛: NOIP2016模拟赛——By Marvolo 丢脸记
前几天liu_runda来机房颓废,顺便扔给我们一个网址,说这上面有模拟赛,让我们感兴趣的去打一打.一开始还是没打算去看一下的,但是听std说好多人都打,想了一下,还是打一打吧,打着玩,然后就丢脸了. ...
- 6424. 【NOIP2019模拟2019.11.13】我的订书机之恋
题目描述 Description Input Output Sample Input 见下载 Sample Output 见下载 Data Constraint 题解 lj题卡线段树 求出每个右端点往 ...
- [CSP-S模拟测试]:砍树(数学+模拟)
题目传送门(内部题1) 输入格式 第一行两个整数$n$,$k$,代表树苗的数量和最大看书的总长度.第二行n个整数$a_i$,代表林先森希望每棵树苗的最终高度. 输出格式 一行一个整数,代表最大可能的d ...
- 2019.8.1 NOIP模拟测试11 反思总结
延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...
随机推荐
- java网络通信:同步阻塞式I/O模型(BIO)
缺点:一个线程只能处理一个客户端连接 服务端: public class TimeServer { public static void main(String[] args) throws IOEx ...
- Openstack 实现技术分解 (1) 开发环境 — Devstack 部署案例详解
目录 目录 前言 系统环境 Devstack 下载源码 配置文件 local.conf & localrc 简易的环境脚本 openrc 部署 Devstack 自动化部署流程 部署案例 单节 ...
- Jmeter接口测试系列之测试用例变量参数化处理
在进行接口测试时,一组完整的接口测试用例,存在后一个测试用例使用前一个用例的请求结果中的数据,此时就需要参数化测试用例中值.直接使用变量调用会存在问题,此时就需要用到beanshell去改变. 举例说 ...
- ubuntu使用iptables 持久化
iptables 持久化 安装持久化工具apt-get install iptables-persistent Ubuntu 16.04 调用语法netfilter-persistent savene ...
- P3951小凯的疑惑
这是2017年提高组的第一题,是一个小学奥数题?听说很多大佬爆零了,我AC了,,, 这个题首先给出两个素数,问取任意个这两个素数之和不可以达到的最大的数是多少?拿到这个题首先很蒙,于是试了试样例,并没 ...
- python day1-requests
一.什么是requests Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库. 相对于urllib库(自带,无需手动安装)而言, ...
- Python数据结构与算法?
数据结构与算法(Python) 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是 ...
- POJ 3414 Pots (BFS/DFS)
Pots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7783 Accepted: 3261 Special Ju ...
- 区块链开源实现hyperledger fabric架构详解
hyperledger fabric是区块链中联盟链的优秀实现,主要代码由IBM.Intel.各大银行等贡献,目前v1.1版的kafka共识方式可达到1000/s次的吞吐量.本文中我们依次讨论:区块链 ...
- jquery TAB切换小插件
//tab切换 ;(function($, window, document, undefined) { $.fn.tab = function(options) { var defaults = { ...