【问题描述】
众所周知,zzh 和 heyi 是一对竹马竹马,他们从小一起学 C++,最后都成了著名的神犇。而时间回溯到他们童年,这天 zzh 邀请 heyi 来参加 zzh 举行的男性家庭聚会。
而 zzh 则在苦恼该邀请哪些人。
我们按照一定的顺序给家庭成员编号,为了表示尊敬,我们给辈分最大的人编号为
1。每个人都有一定的身价,为了避免尴尬,我们希望邀请的所有家庭成员中每个人的身价都必须要小于他的直系长辈,此时 zzh 想知道最多能邀请多少人。
注意:直系长辈只包含父亲祖父等,叔叔不算。
【输入格式】
输入文件名为 chikuma.in。
输入文件第一行为一个正整数 n。
接下来 n 行,每行两个非负整数vi,pi,表示 i 号成员的身价与父亲。
【输出格式】
输出文件名为 chikuma.out。
输出文件包含 1 行,一个正整数,表示最多能邀请的人数。
【输入输出样例】
chikuma.in
chikuma.out
6
3 0
1 1
2 1
3 1
4 1
5 1
5
【输入输出样例说明】
2~6 号家庭成员的直系长辈为 1 号家庭成员。
如果 zzh 不邀请 1 号家庭成员,那么 2~6 号家庭成员都能参加,能够邀请 5 个人。
如果 zzh 邀请 1 号家庭成员,那么由于 3 号、4 号和 5 号家庭成员身价不低于 1 号
家庭成员,将不能被邀请,因此能够邀请 3 个人。
因此,最多能邀请 5 个人。
【数据范围】
对于 10%的数据,n≤10。
对于 40%的数据,n≤1000。
另有 10%的数据,保证不存在有叔叔的情况
对于 100%的数据,n≤200000,0≤vi≤1e9,
1≤pi<i,p1=0。
【题解】
对于40分做法:设f[i][j]表示以i为根的子树中选出的人最大身价的人为j的时候最多选出几个人,转移很简单。
对于100分做法:

线段树合并

线段树中叶节点表示最大为该身价时可选人数,非叶节点维护最大值,答案即为shu[root[1]].mx。

插入只需将线段树从根到表示v[u]的节点路径上,mx全部取max ((1-v[u]-1)中最大值+1)即可。

合并时右儿子对左边的所有的max取max。

即为区间取最大值,单点修改,区间查询。

维护该子树中身价最多为i时最多可选人数。

代码如下:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=,f=;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f==?x:-x;
}
int cn;
const int N=2e5+;
struct segment_tree{
#define lc ch[p][0]
#define rc ch[p][1]
int t[N<<],ch[N<<][],tot,lazy[N<<];
void pushup(int p)
{
t[p]=max(t[lc],t[rc]);
}
void pushdown(int p)
{
if(lc)
{
t[lc]+=lazy[p];
lazy[lc]+=lazy[p];
}
if(rc)
{
t[rc]+=lazy[p];
lazy[rc]+=lazy[p];
}
lazy[p]=;
}
void merge(int &p,int pre,int l,int r,int lx,int ly){
if(!p && !pre) return;
if(!pre)
{
lazy[p]+=ly;
t[p]+=ly;
return;
}
if(!p)
{
lazy[pre]+=lx;
t[pre]+=lx;
p=pre;
return;
}
if(l==r)
{
t[p]+=max(ly,t[pre]);
return;
}
int mid=(l+r)>>;
pushdown(p);
pushdown(pre);
merge(rc,ch[pre][],mid+,r,max(lx,t[lc]),max(ly,t[ch[pre][]]));
merge(lc,ch[pre][],l,mid,lx,ly);
pushup(p);
}
void insert(int &p,int l,int r,int x,int v){
if(!p)p=++tot;
t[p]=max(t[p],v);
if(l==r)return;
int mid=l+r>>;
if(x<=mid) insert(lc,l,mid,x,v);
else insert(rc,mid+,r,x,v);
}
int query(int p,int l,int r,int ql,int qr){
if(!p)return ;
if(ql<=l&&r<=qr)return t[p];
int mid=l+r>>,ret=;
pushdown(p);
if(ql<=mid)ret=max(ret,query(lc,l,mid,ql,qr));
if(mid<qr)ret=max(ret,query(rc,mid+,r,ql,qr));
return ret;
}
}seg;
struct edge{
int v,nxt;
}e[N];
int first[N],cnt=;
inline void add(int u,int v){
e[++cnt].v=v;e[cnt].nxt=first[u];first[u]=cnt;
}
int n,a[N],b[N],rt[N];
inline void dfs(int x){
for(int i=first[x],v,v1,v2;i;i=e[i].nxt){
v=e[i].v;
dfs(v);
v1=v2=;
seg.merge(rt[x],rt[v],,cn,v1,v2);
}
seg.insert(rt[x],,cn,a[x],((a[x]==)?:(seg.query(rt[x],,cn,,a[x]-)+)));
}
int main(){
freopen("chikuma.in","r",stdin);
freopen("chikuma.out","w",stdout);
long long size = << ;
char *p = (char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p));
n=read();
for(int i=,x;i<=n;i++){
b[i]=a[i]=read();x=read();
if(x) add(x,i);
}
sort(b+,b+n+);
cn=unique(b+,b+n+)-b-;
for(int i=;i<=n;i++)
a[i]=lower_bound(b+,b+cn+,a[i])-b;
dfs();
cout<<seg.t[rt[]];
fclose(stdin);
fclose(stdout);
return ;
}
/*
6
3 0 1 1 2 1 3 1 4 1 5 1
*/

竹马竹马chikuma的更多相关文章

  1. [Swust OJ 772]--Friend(并查集+map的运用)

    题目链接:http://acm.swust.edu.cn/problem/772/ Time limit(ms): 1000 Memory limit(kb): 65535    Descriptio ...

  2. python --常用内置模块01

    1.简单了解模块         模块就是我们把装有特定功能的代码进行归类的解构,从代码编写的单位来看我们的程序 从小到大的顺序:一条代码< 语句块<代码块(函数,类) < 模块 我 ...

  3. qwq。。胡诌qwq

    1,十里寒塘,红楼灯火阑珊,晓风残月,思念醒了一半. 晨钟催落月,淑气催黄鸟,而花千树而你还未还,三月烟花,只剩远影孤帆,珠箔飘灯,大雁独自来返,柳絮铺地,桃花落了菀晚, 琴声弹起,雨落长安,长夜漫漫 ...

  4. 佛山6397.7539(薇)xiaojie:佛山哪里有xiaomei

    佛山哪里有小姐服务大保健[微信:6397.7539倩儿小妹[佛山叫小姐服务√o服务微信:6397.7539倩儿小妹[佛山叫小姐服务][十微信:6397.7539倩儿小妹][佛山叫小姐包夜服务][十微信 ...

  5. 宜宾1178.9873(薇)xiaojie:宜宾哪里有xiaomei

    宜宾哪里有小姐服务大保健[微信:1178.9873倩儿小妹[宜宾叫小姐服务√o服务微信:1178.9873倩儿小妹[宜宾叫小姐服务][十微信:1178.9873倩儿小妹][宜宾叫小姐包夜服务][十微信 ...

随机推荐

  1. torch中的copy()和clone()

    torch中的copy()和clone() 1.torch中的copy()和clone() y = torch.Tensor(2,2):copy(x) ---1 修改y并不改变原来的x y = x:c ...

  2. 读取Flex AIR应用程序设置

    说明: 本人之前做过一年的Flex AIR移动跨平台开发,在之前学习过程中,一直是将笔记记在了Evernote上,有的笔记是自己写的,也有的笔记是在网上看到,顺手记下了的. 所以在这里声明下,如果在网 ...

  3. H3C NAPT配置举例

  4. java一维数组的声明与初始化

    一维数组:可以理解为一列多行.类型相同的数据,其中每个数据被称为数组元素: 一维数组的声明方式: type varName[]; 或 type[] varName;(推荐) Eg:int age[]; ...

  5. Java 自带性能监控工具:监视和管理控制台 jconsole 的使用

    1. 前言想验证你对 jvm 配的一些调优参数(比如 Xms.Xmx 等)有没有起作用吗?想不想实时监控你自定义的线程池的在实际运行时的线程个数.有没有死锁?应用出现 java.lang.OutOfM ...

  6. React 蚂蚁金服+ Antd 组件使用技巧

    安装antd 组件 yarn add antd -D import {  Card,Button,Table,From,Modal ,Select  } from 'antd'; .引入就可以使用了 ...

  7. Roslyn 使用 Directory.Build.props 管理多个项目配置

    在一些大项目需要很多独立的仓库来做,每个仓库之间都会有很多相同的配置,本文告诉大家如何通过 Directory.Build.props 管理多个项目配置 在我的 MVVM 框架需要三个不同的库,一个是 ...

  8. Vue中qs插件的使用

    qs 是一个增加了一些安全性的查询字符串解析和序列化字符串的库. 在项目中使用命令行工具输入:npm install qs安装完成后在需要用到的组件中:import qs from ‘qs’具体使用中 ...

  9. H3C查看系统启动配置文件

  10. [Ctsc2014]图的分割

    [Ctsc2014]图的分割 阅读理解好题 翻译一下: M(C)就是C这个诱导子图最小生成树最大边权 结论: 按照w进行sort,如果满足w<=Ci,Cj表示u,v的连通块的诱导子图 并且Ci! ...