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. 每次操作要求输出权值更改的节点个数. 解题思路: 显然是用树 ...
随机推荐
- In-App Purchase Programming Guide----(八) ---- Preparing for App Review
Preparing for App Review After you finish testing, you’re ready to submit your app for review. This ...
- 数据库路由中间件MyCat - 源代码篇(17)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 调用processInsert(sc,schema,sqlType,origSQL,tableName,pr ...
- CMD运行指令
CMD运行指令 开始→运行→CMD→键入以下命令即可: gpedit.msc-----组策略 sndrec32-------录音机 Nslookup-------IP地址侦测器 explo ...
- shell初级-----构建基本脚本
使用多个命令 如果想要多个命令同时运行,可以把它们放在一行,用分号隔开. date;who 创建shell脚本文件 创建shell脚本时,必须在文件第一行指定要使用的shell #!/bin/bash ...
- this解惑
前言 要正确理解this,首先得理解执行上下文,这里推荐汤姆大叔的执行上下文,因为this是在运行代码时确认具体指向谁,箭头函数除外. 全局作用域中的this node: 每个javaScript文件 ...
- 谷歌同声翻译Translatotron原理
背景介绍 作为中国人,学好英语这件事从小学开始就让人苦恼,近些年随着AI的快速发展,语言差异是否会缩小甚至被消灭成了热门话题.在5月15日,谷歌AI在博客平台发出一篇文章,正式介绍了一款能保留原声的& ...
- codevs3002 石子归并3
3002 石子归并 3 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安 ...
- jzoj6001. 【PKUWC2019模拟2019.1.15】Mines (tarjan)
题面 题解 我们把每个地雷向它能炸到的地雷连边,不难发现同一个强联通分量里的点只要一个炸全炸 那么我们缩点,首先所有入度为\(0\)的强联通分量中必须得选一个地雷炸掉,而入度不为\(0\)的强联通分量 ...
- jquery插件fileupload图片上传(前端如何处理)
1.页面首先引入jquery,版本不要低于1.6 <script src="../js/jquery.min.js"></script>2.其次页面引入对应 ...
- 深入V8引擎-Time模块介绍
积跬步,行千里,先从最简单的开始写. 这一篇介绍V8中的时间模块,与libuv粗糙的update_loop_time方法不同,V8有一套独立完整的类负责管理时间. 该类位于src/base/platf ...