内存限制:256 MiB 时间限制:1000 ms 标准输入输出
                           题目类型:传统 评测方式:文本比较
                                上传者: 匿名

树链剖分+线段树

屠龙宝刀点击就送

#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」软件包管理器的更多相关文章

  1. 【LOJ】 #2130. 「NOI2015」软件包管理器

    题解 连树剖我都写跪一次,我现在怎么那么老年啊= = 简直滚粗预定了啊.. 我们线段树维护树剖只需要资瓷区间覆盖和区间求和就好了 安装的时候看看自己到根有多少包装了,dep减去这个数量就好 卸载的时候 ...

  2. 「NOI2015」软件包管理器

    题目描述 题面比较啰唆,我先把大体意思讲一下: 首先,有编号从\(0\)到\(N-1\)的\(N\)个节点,根节点一定是\(0\)号节点(无前驱) (我把下标都加上了一,转化为以\(1\)为起始下标的 ...

  3. 「NOI2015」「Codevs4621」软件包管理器(树链剖分

    4621 [NOI2015]软件包管理器 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond   题目描述 Description Linux用户和OSX用户一定对 ...

  4. 【BZOJ4196】【NOI2015】软件包管理器(树链剖分,线段树)

    [BZOJ4196][NOI2015]软件包管理器 题面 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你 ...

  5. BZOJ_4196_[NOI2015]_软件包管理器_(树链剖分)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=4196 给出一棵树,树上点权为0或1.u权值为1的条件是从根节点到u路径上的所有点权值都为1.u ...

  6. 【NOI2015】 软件包管理器 - 树链剖分

    noi2015 软件包管理器 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软 ...

  7. 【NOI2015】软件包管理器

    NOI难得的水题,话说还是T2诶……又学到了线段树的一种新的魔性使用 看sxysxy大神的代码才写出来的,sxysxy_orz 原题: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包 ...

  8. NOI2015 D1T2 软件包管理器

    题目传送门; 这个貌似是我这个蒟蒻做的第一道NOI系列的题了吧...这题的算法是树链剖分,其实基本上就是很常见的树剖+线段树,题目既然是要求每次安装或卸载改变的软件包的数目,那么就在每次操作前记录下线 ...

  9. 【BZOJ4196】【Noi2015】软件包管理器

    原题传送门 题意: 给你一棵树,有2种操作: 1.使得某个点到根节点路径上的所有点权值赋为1. 2.使得某节点的子树中所有节点权值赋为0. 每次操作要求输出权值更改的节点个数. 解题思路: 显然是用树 ...

随机推荐

  1. 廖雪峰的java教程

    F:\教程\0-免费下载-廖雪峰 公司电脑地址: G:\学习中\廖雪峰的java教程 廖雪峰java课程地址: https://www.feiyangedu.com/category/JavaSE 0 ...

  2. 23.Consent 代码重构

    新建Services文件,并新建类ConsentService类把,ConsetController里面不是Action的方法都放在这个ConsentService类里面 先把构造函数完善 把这些私有 ...

  3. Linux 之添加系统环境变量

    PATH 值是一系列目录,当执行命令时,linux就在这些目录下查找,其格式为: PATH=$PATH:<PATH1>:<PATH2>:<PATH3>:------ ...

  4. Kolla多节点环境安装OVN

    安装OVN组件 控制节点 ### 安装ovn-northd # wget https://copr.fedorainfracloud.org/coprs/leifmadsen/ovs-master/r ...

  5. SCUT - 299 - Kaildls的数组划分 - dp - 高精

    https://scut.online/p/299 \(dp[i][k]\) 为前 \(i\) 个数分 \(k\) 组的最大值,那么 $dp[i][k]=max_{p=1}^{i-1}{dp[p][k ...

  6. 编写BeanFactory

    /** * 一个创建Bean对象的工厂 * * Bean:在计算机英语中,有可重用组件的含义. * JavaBean:用java语言编写的可重用组件. * javabean > 实体类 * * ...

  7. Widows下Faster R-CNN的MATALB配置(GPU)

    目录 1. 准备工作 2. VS2013编译Caffe 3. Faster R-CNN的MATLAB源码测试 说在前面,这篇是关于Windows下Faster R-CNN的MATLAB配置,GPU版本 ...

  8. 洛谷P1654 产品排序(sort)

    P1654 产品排序(sort) 题目描述 有一系列产品,给定每个产品的加工时间和冷却成型时间(冷却过程产品之间没有关系,是单独冷却的).现在你手上有两台机器可以用来加工,你需要安排产品加工的顺序以及 ...

  9. Linux上安装Apache服务器

    http://httpd.apache.org/download.cgi httpd-2.4.29.tar.gz #创建httpd用户 groupadd httpd useradd -g httpd ...

  10. 原生js 的ajax封装

    /** * 封装ajax函数(包括跨域) * @method ajax * @param option :{type:"post" or "get" 请求方式, ...