LibreOJ #2130. 「NOI2015」软件包管理器



树链剖分+线段树
#include <vector>
#include <cstdio>
#define N 100005 using namespace std;
vector<int>G[N];
int n,q,tim,siz[N],fa[N],dep[N],belong[N],top[N];
struct Segment
{
int l,r,mid,sum,flag;
Segment *ch[];
Segment()
{
ch[]=ch[]=NULL;
sum=flag=;
}
}*root=new Segment;
void dfs1(int x)
{
siz[x]=;
dep[x]=dep[fa[x]]+;
for(int i=;i<G[x].size();++i)
{
int v=G[x][i];
if(fa[x]!=v)
{
fa[v]=x;
dfs1(v);
siz[x]+=siz[v];
}
}
}
void dfs2(int x)
{
if(!top[x]) top[x]=x;
int t=;
belong[x]=++tim;
for(int i=;i<G[x].size();++i)
{
int v=G[x][i];
if(fa[x]!=v&&siz[t]<siz[v]) t=v;
}
if(t) top[t]=top[x],dfs2(t);
for(int i=;i<G[x].size();++i)
{
int v=G[x][i];
if(fa[x]!=v&&v!=t) dfs2(v);
}
}
inline void pushup(Segment *&k) {k->sum=k->ch[]->sum+k->ch[]->sum;}
void build(Segment *&k,int l,int r)
{
k=new Segment;
k->l=l;k->r=r;
if(l==r) return;
k->mid=(l+r)>>;
build(k->ch[],l,k->mid);
build(k->ch[],k->mid+,r);
pushup(k);
}
void swap(int &m,int &n)
{
int tmp=n;
n=m;
m=tmp;
}
void pushdown(Segment *&k)
{
if(k->flag==)
{
k->ch[]->flag=k->flag;
k->ch[]->sum=k->ch[]->r-k->ch[]->l+;
k->ch[]->flag=k->flag;
k->ch[]->sum=k->ch[]->r-k->ch[]->l+;
k->flag=;
}
else
{
k->ch[]->flag=k->flag;
k->ch[]->sum=;
k->ch[]->flag=k->flag;
k->ch[]->sum=;
k->flag=;
}
}
int Tree_Query(Segment *&k,int l,int r)
{
if(k->l==l&&k->r==r) return k->sum;
if(k->flag) pushdown(k);
if(l>k->mid) return Tree_Query(k->ch[],l,r);
else if(r<=k->mid) return Tree_Query(k->ch[],l,r);
else return Tree_Query(k->ch[],l,k->mid)+Tree_Query(k->ch[],k->mid+,r);
pushup(k);
}
void Tree_Change(Segment *&k,int l,int r,int opt)
{
if(k->l==l&&k->r==r)
{
k->flag=opt;
if(opt==) k->sum=r-l+;
else k->sum=;
return;
}
if(k->flag) pushdown(k);
if(l>k->mid) Tree_Change(k->ch[],l,r,opt);
else if(r<=k->mid) Tree_Change(k->ch[],l,r,opt);
else Tree_Change(k->ch[],l,k->mid,opt),Tree_Change(k->ch[],k->mid+,r,opt);
pushup(k);
}
int Chain_Query(int x,int y)
{
int ret=;
for(;top[x]!=top[y];x=fa[top[x]])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret+=Tree_Query(root,belong[top[x]],belong[x]);
}
if(dep[x]<dep[y]) swap(x,y);
ret+=Tree_Query(root,belong[y],belong[x]);
return ret;
}
void Chain_Change(int x,int y,int opt)
{
for(;top[x]!=top[y];x=fa[top[x]])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
Tree_Change(root,belong[top[x]],belong[x],opt);
}
if(dep[x]<dep[y]) swap(x,y);
Tree_Change(root,belong[y],belong[x],opt);
}
int Main()
{
scanf("%d",&n);
for(int pr,i=;i<=n;++i)
{
scanf("%d",&pr);
G[++pr].push_back(i);
G[i].push_back(pr);
}
dfs1();
dfs2();
build(root,,n);
scanf("%d",&q);
char opt[];
for(int x;q--;)
{
scanf("%s%d",opt,&x);++x;
if(opt[]=='i')
{
int ans=Chain_Query(,x);
Chain_Change(,x,);
printf("%d\n",dep[x]-ans);
}
else
{
int ans=Tree_Query(root,belong[x],belong[x]+siz[x]-);
Tree_Change(root,belong[x],belong[x]+siz[x]-,);
printf("%d\n",ans);
}
}
return ;
}
int sb=Main();
int main(int argc,char *argv[]) {;}
LibreOJ #2130. 「NOI2015」软件包管理器的更多相关文章
- 【LOJ】 #2130. 「NOI2015」软件包管理器
题解 连树剖我都写跪一次,我现在怎么那么老年啊= = 简直滚粗预定了啊.. 我们线段树维护树剖只需要资瓷区间覆盖和区间求和就好了 安装的时候看看自己到根有多少包装了,dep减去这个数量就好 卸载的时候 ...
- 「NOI2015」软件包管理器
题目描述 题面比较啰唆,我先把大体意思讲一下: 首先,有编号从\(0\)到\(N-1\)的\(N\)个节点,根节点一定是\(0\)号节点(无前驱) (我把下标都加上了一,转化为以\(1\)为起始下标的 ...
- 「NOI2015」「Codevs4621」软件包管理器(树链剖分
4621 [NOI2015]软件包管理器 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description Linux用户和OSX用户一定对 ...
- 【BZOJ4196】【NOI2015】软件包管理器(树链剖分,线段树)
[BZOJ4196][NOI2015]软件包管理器 题面 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你 ...
- BZOJ_4196_[NOI2015]_软件包管理器_(树链剖分)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=4196 给出一棵树,树上点权为0或1.u权值为1的条件是从根节点到u路径上的所有点权值都为1.u ...
- 【NOI2015】 软件包管理器 - 树链剖分
noi2015 软件包管理器 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软 ...
- 【NOI2015】软件包管理器
NOI难得的水题,话说还是T2诶……又学到了线段树的一种新的魔性使用 看sxysxy大神的代码才写出来的,sxysxy_orz 原题: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包 ...
- NOI2015 D1T2 软件包管理器
题目传送门; 这个貌似是我这个蒟蒻做的第一道NOI系列的题了吧...这题的算法是树链剖分,其实基本上就是很常见的树剖+线段树,题目既然是要求每次安装或卸载改变的软件包的数目,那么就在每次操作前记录下线 ...
- 【BZOJ4196】【Noi2015】软件包管理器
原题传送门 题意: 给你一棵树,有2种操作: 1.使得某个点到根节点路径上的所有点权值赋为1. 2.使得某节点的子树中所有节点权值赋为0. 每次操作要求输出权值更改的节点个数. 解题思路: 显然是用树 ...
随机推荐
- 《Java多线程编程核心技术》读后感(十一)
方法join的使用 在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束之前结束.这时,如果主线程想等待子线程执行完之后再结束,比如子线程处理一个数据,主 ...
- day1 java基础回顾-Junit单元测试
Junit单元测试框架的基本使用 一.搭建环境: 导入junit.jar包(junit4) 二.写测试类: 0,一般一个类对应一个测试类. 1,测试类与被测试类最好是放到同一个包中(可以是不同的源文件 ...
- Fluuter常遇到的问题
The ADB binary found at XX is obsolete and has seriousperformance problems with the Android Emulator ...
- 【异步编程】Part1:await&async语法糖让异步编程如鱼得水
前导 Asynchronous programming Model(APM)异步编程模型以BeginMethod(...) 和 EndMethod(...)结对出现. IAsyncResult Beg ...
- pandas基础(1)_Series和DataFrame
1:pandas简介 Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一些标 ...
- ue4 碰撞检测测试
记录几条物理相关 测试条件,1使用setActorLocation移动,3使用控制器的移动 1 moveCube 2 targetCube 3 Character 两个Cube的碰撞事件 1和2的 ...
- Solr 6.7学习笔记(02)-- 配置文件 managed-schema (schema.xml) - Analyzer, tokenizer(4)
有些时候,我们需要自定义 fieldType.下面的例子就是自定义的 fieldType,<analyzer type="index"> 表示索引时怎么处理,<a ...
- 一站式解决方案:springboot
优点: ·轻松创建独立的spring应用 ·内嵌tomcat.jetty等web容器,不需要部署war文件 ·提供一系列的“starter”来简化maven配置 ·开箱即用,尽可能自动配置spring
- [Java]三大特性之封装
封装这个我们可以从字面上来理解,简单来说就是包装的意思,专业点就是信息隐藏. 是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可 ...
- C-晾衣服
链接:https://ac.nowcoder.com/acm/contest/892/C 题意: 鸡尾酒从杭州回来,囤积了许多衣服,洗好之后,他发现晾衣服是一件麻烦的事. 晾衣绳的长度只有L,而鸡尾酒 ...