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. 每次操作要求输出权值更改的节点个数. 解题思路: 显然是用树 ...
随机推荐
- JMeter聚合报告(Aggregate Report)理解
部分内容转载: http://blog.csdn.net/lion19930924/article/details/51189218 http://www.cnblogs.com/fnng/archi ...
- HDU - 3001 Travelling(三进制状压dp)
Travelling After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best ch ...
- RPC原理与实践(二)----Thrift分层模型
这一节我们从一下几个方面来讲一下Thrift的分层架构,按照官方的定义这是Thrift的网络栈,其中网络栈中分为一下几个部分,(由栈顶到栈底)server,processor,protocol,tra ...
- Fiddler如何抓取HTTPS协议的网页
Fiddler默认只能抓取HTTP协议的网页,不能抓取HTTPS协议的网页,而我们很多时候,都需要抓HTTPS协议的网页,比如抓淘宝数据等.今天,韦玮老师会为大家讲解如何使用Fiddler抓取HTTP ...
- this解惑
前言 要正确理解this,首先得理解执行上下文,这里推荐汤姆大叔的执行上下文,因为this是在运行代码时确认具体指向谁,箭头函数除外. 全局作用域中的this node: 每个javaScript文件 ...
- MapReduce编程模型
# 文本前期处理 strl_ist = str.replace('\n', '').lower().split(' ') count_dict = {} # 如果字典里有该单词则加 1,否则添加入字典 ...
- 3dmax视频
http://wenku.baidu.com/course/list/514?tagID=177
- 原生js 的ajax封装
/** * 封装ajax函数(包括跨域) * @method ajax * @param option :{type:"post" or "get" 请求方式, ...
- wampserver2.5局域网公网IP访问配置
wampserver2.5集成环境的安装和使用就不多说了,网上有很多教材.安装好后找到apache的配置文件httpd.conf.默认位置是: swap安装目录\wamp\bin\apache\apa ...
- Java:创建线程
Java定义了两种创建线程的方法: 1.实现Runnable接口 要实现Runnable接口,只需简单地实现run()方法即可,声明如下:public void run() 在run()方法中,可以定 ...