【主席树/DFS】Gym - 101848C - Object-Oriented Programming

题目链接http://codeforces.com/gym/101848/problem/C


题意:

有n个类,每个类都定义了一些方法,而且每个类都会继承另一个类(1号类除外)。
q次询问,每次询问一个类调用一个方法,问所调用的方法是哪一个类里写的。所有申明的方法数不超过1e6。


题解:

大多是DFS写的,我这里提供一个主席树的方法。
每一个类建一个方法的线段树,记录的是最近申明的方法,也就是答案。
因为方法总数不超过1e6,所以最后空间大概是4e7级别。
而且线段树只有叶子节点才会有用,在这里的线段树只是起一个二分作用。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+7;
int t[N*40],rt[N],ls[N*40],rs[N*40],p[N],tot;

int upd(int o,int l,int r,int x,int y){
    int now=++tot;
    if(l==r){
        t[now]=y;
        return now;
    }
    ls[now]=ls[o];rs[now]=rs[o];
    int m=l+r>>1;
    if(x<=m) ls[now]=upd(ls[o],l,m,x,y);
    else rs[now]=upd(rs[o],m+1,r,x,y);
    return now;
}
int que(int o,int l,int r,int x){
    if(l==r) return t[o];
    int m=l+r>>1;
    if(x<=m) return que(ls[o],l,m,x);
    return que(rs[o],m+1,r,x);
}
int main(){
    int n,q;
    memset(t,-1,sizeof(t));
    scanf("%d",&n);
    for(int i=2,x;i<=n;i++){
        scanf("%d",&p[i]);
    }
    int lst=0;
    for(int i=1,m,x;i<=n;i++){
        scanf("%d",&m);
        rt[i]=rt[p[i]];
        while(m--){
            scanf("%d",&x);
            rt[i]=upd(rt[i],1,N,x,i);
        }
    }
    scanf("%d",&q);
    int x,y;
    while(q--){
        scanf("%d%d",&x,&y);
        printf("%d\n",que(rt[x],1,N,y));
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值