真没有想到,这竟然会是一道NOI的原题,听RQY说,这套题是北大出的,北大脑抽认为树剖很难。。。

只恨没有早学几年OI,只A这一道题也可以出去吹自己一A了NOI原题啊

好了,梦该醒了,我们来看题

以后放链接不放题面了,洛谷题面直接拷出来总是很迷

我是题面

读完题,我们会发现,这道题,好像是,树剖???裸题???

没错,就是裸题

题目要求两种操作,先说第一种

安装程序\(x\),并输出修改状态的程序数目。

就是从\(x\)一直查询+更新到根节点呗,节点数目减去已安装的数目就是答案,先查询,再更新,当然,操作和到一起也可以

第二种操作更无语,卸载程序\(x\)并输出修改状态的程序数目

说白了也就是看\(x\)的子树上安装了几个程序呗

那么线段树上,我们用1表示已安装,0表示未安装,一切就很显然了

上代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#define ll long long
#define gc() getchar()
#define maxn 100005
using namespace std; inline ll read(){
ll a=0;int f=0;char p=gc();
while(!isdigit(p)){f|=p=='-';p=gc();}
while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
return f?-a:a;
}
void write(ll a){
if(a>9)write(a/10);
putchar(a%10+'0');
}
int n,m; int tot,head[maxn];
struct ahaha1{
int to,next;
}e[maxn<<1];
inline void add(int u,int v){
e[tot].to=v;e[tot].next=head[u];head[u]=tot++;
} int f[maxn],sz[maxn],son[maxn],dep[maxn];
void dfs(int u,int fa){
int maxa=0;sz[u]=1;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;if(v==fa)continue;
f[v]=u;dep[v]=dep[u]+1;
dfs(v,u);sz[u]+=sz[v];
if(sz[v]>maxa)maxa=sz[v],son[u]=v;
}
}
int top[maxn],in[maxn],b[maxn];
void dfs(int u,int fa,int topf){
top[u]=topf;in[u]=++tot;b[tot]=u;
if(!son[u])return;
dfs(son[u],u,topf);
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;if(v==fa||v==son[u])continue;
dfs(v,u,v);
}
} #define lc p<<1
#define rc p<<1|1
struct ahaha2{
int v,lz;
ahaha2(){
lz=-1;
}
}t[maxn<<2];
inline void pushup(int p){
t[p].v=t[lc].v+t[rc].v;
}
inline void pushdown(int p,int l,int r){
int m=l+r>>1;
t[lc].v=t[p].lz*(m-l+1);t[lc].lz=t[p].lz;
t[rc].v=t[p].lz*(r-m);t[rc].lz=t[p].lz;
t[p].lz=-1;
}
ll query1(int p,int l,int r,int L,int R){ //安装程序的操作
if(l>R||r<L)return 0;
if(L<=l&&r<=R){int v=t[p].v;t[p].v=r-l+1;t[p].lz=1;return v;} //通过先存储返回值然后进行修改来合并操作
int m=l+r>>1;if(t[p].lz!=-1)pushdown(p,l,r);
int l1=query1(lc,l,m,L,R),r1=query1(rc,m+1,r,L,R); //同上
pushup(p);
return l1+r1;
}
ll query2(int p,int l,int r,int L,int R){ //卸载程序的操作
if(l>R||r<L)return 0;
if(L<=l&&r<=R){int v=t[p].v;t[p].v=0;t[p].lz=0;return v;}
int m=l+r>>1;if(t[p].lz!=-1)pushdown(p,l,r);
int l1=query2(lc,l,m,L,R),r1=query2(rc,m+1,r,L,R);
pushup(p);
return l1+r1;
} inline void solve_1(){
int x=read(),ans1=0,ans2=0;
while(top[x]){
ans1+=in[x]-in[top[x]]+1; //别忘了+1
ans2+=query1(1,1,n,in[top[x]],in[x]);
x=f[top[x]];
}
ans1+=in[x]-in[0]+1;
ans2+=query1(1,1,n,in[0],in[x]);
write(ans1-ans2);putchar('\n');
}
inline void solve_2(){
int x=read();
write(query2(1,1,n,in[x],in[x]+sz[x]-1));putchar('\n'); //直接子树比安装简单多了
} int main(){memset(head,-1,sizeof head);
n=read();
for(int i=1;i<n;++i){
int a=read();
add(a,i);
}
tot=0;dfs(0,-1);dfs(0,-1,0);
m=read();
string z;
for(int i=1;i<=m;++i){
cin>>z;
switch(z[0]){
case 'i':solve_1();break;
case 'u':solve_2();break;
}
}
return 0;
}

洛谷 P2146 [NOI2015]软件包管理器的更多相关文章

  1. 洛谷 P2146 [NOI2015]软件包管理器 解题报告

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

  2. 洛谷 P2146 [NOI2015]软件包管理器 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 输出样例#1: 输入样例#2: 输出样例#2: 说明 说明 思路 AC代码 总结 题面 题目链接 P ...

  3. 洛谷 P2146 [NOI2015]软件包管理器 (树链剖分模板题)

    题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...

  4. 洛谷P2146 [NOI2015]软件包管理器

    https://www.luogu.org/problemnew/show/P2146 传送门 简单的树链剖分......维护下当前安装了多少个包......修改后查询下就行了......附上极其丑陋 ...

  5. 洛谷P2146 [NOI2015]软件包管理器 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2146 本题涉及算法: 树链剖分: 线段树(区间更新及求和,涉及懒惰标记) 然后对于每次 install x ,需要将 x 到 ...

  6. 洛谷 pP2146 [NOI2015]软件包管理器

    题目的传送门 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖( ...

  7. 洛谷 2146 [NOI2015]软件包管理器

    [题解] 每个软件只依赖另一个软件,且依赖关系不构成环,那么很容易想到这是树形结构. 我们用1表示以安装,用0表示未安装或已卸载:那么安装一个软件,就是把它到树根的路径上所有的点都改为1:卸载一个软件 ...

  8. 题解 P2146 [NOI2015]软件包管理器

    P2146 [NOI2015]软件包管理器 感觉代码比其他题解更简洁qwq 树链剖分模板题 install x:将1~x的路径上的节点全部变成1(安装x需要先安装1~x) uninstall x:将x ...

  9. P2146 [NOI2015]软件包管理器

    题目链接:https://www.luogu.org/problemnew/show/P2146 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安 ...

随机推荐

  1. mongdb基础

    查看数据库 show dbs; 切换到需要使用的数据库:use local; 显示集合中的数据库表:show collections; 切换到数据库test,如果数据库不存在,则自动创建 插入数据 d ...

  2. Azkaban 工作流调度器

    Azkaban 工作流调度器 1 概述 1.1 为什么需要工作流调度系统 a)一个完整的数据分析系统通常都是由大量任务单元组成,shell脚本程序,java程序,mapreduce程序.hive脚本等 ...

  3. C语言的函数调用过程(栈帧的创建与销毁)

    从汇编的角度解析函数调用过程 看看下面这个简单函数的调用过程: int Add(int x,int y) { ; sum = x + y; return sum; } int main () { ; ...

  4. Django-建立网页

    进入cmd模式做 django-admin startproject helloworld创建一个project,并命名helloworld,新生成的文件结构如下   输入python manage. ...

  5. 机器学习与R语言——基本语法

    一.注释 1.选中要注释的内容,快捷键Ctrl+Shift+C(取消注释方法相同) 2.在需注释内容前输入# #需注释的内容 3.利用if语句,将判断条件设置为false则可跳过if语句中的内容,相当 ...

  6. 基于C#的机器学习--模糊逻辑-穿越障碍

    模糊逻辑-穿越障碍 模糊逻辑.另一个我们经常听到的术语.但它的真正含义是什么?它是否意味着不止一件事?我们马上就会知道答案. 我们将使用模糊逻辑来帮助引导一辆自动驾驶汽车绕过障碍,如果我们做得正确,我 ...

  7. [T-ARA][Falling U]

    歌词来源:http://music.163.com/#/song?id=27506041 作词:韩尚元 [作词:韩尚元] 作曲:韩尚元 [作曲:韩尚元] Love is pain Love is pa ...

  8. USACO 2.3.4 Money Systems 货币系统(完全背包)

    Description 母牛们不但创建了他们自己的政府而且选择了建立了自己的货币系统. [In their own rebellious way],,他们对货币的数值感到好奇. 传统地,一个货币系统是 ...

  9. 团队Alpha冲刺(五)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...

  10. sql主表分页查询关联子表取任意一条高效方案

    有个业务场景,主表中一条数据,在子表中有多条详情数据.对数据进行展示的时候,产品希望随意拿一条子表的数据关联展示出来,用了很多方案,但是都不够好. sql查询取子表任意一条,多个字段的方案 最终找到一 ...