C. Object-Oriented Programming
time limit per test

3.0 s

memory limit per test

1024 MB

input

standard input

output

standard output

Functions overriding, is a well-known concept, when we are using inheritance in Object-Oriented Programming (OOP). For those who are not familiar with OOP, I will recall a few things to perhaps refresh your memory.

  • A class has at most one parent class. When they do, they are called subclasses inheriting their parents. Subclasses also inherit all the functions declared in their parent classes, and also, all the functions inherited by parents' parents, and so on. Here, we refer to the ancestors as superclasses.
  • Subclasses can, of course, declare new functions, and also override the functions already declared in superclasses. This is called overriding.
  • When an instance of the subclass calls a function, it will first try to find the code in its own class body, and then its parent, and then its parent's parent, etc., until it reaches the root (the superclass of all classes). If the function has still not been found yet, a runtime error will be raised.

As you might have guessed, we are interested in finding out in which class the function is written when some instance of a particular class calls it.

Input

The input is in the following format:

n (2 ≤ n ≤ 105) is the number of classes. Classes are numbered from 1 to npi (1 ≤ pi ≤ i - 1) is the parent class of class i. Class 1 is the root class, superclass of all classes. It has no parent.

ti denotes the number of functions written in class i, including both new functions and overriding functions. Then follows ai1, ai2, ..., aiti a list of these functions. Functions are also denoted using positive integers. It's guaranteed that every number will appear at most once in one list. 1 ≤ aij ≤ 106, 0 ≤ ti ≤ 106, .

q (1 ≤ q ≤ 105) is the query number. Then follows q queries. uiri (1 ≤ ui ≤ n, 1 ≤ ri ≤ 106) is the i-th query, asking when an instance of class ui calls function ri, in which class is this function written?

Output

For each query, print answer. If it is illegal, that is, a "runtime error" is raised, then output  - 1.

Example
input

Copy
5
1 2 3 3
2 2 1
0
2 5 2
2 4 5
1 5
4
3 4
5 2
4 5
1 3
output

Copy
-1
3
4
-1
Note

The sample is equivalent to the following Java code.

class Class1 {
void function2() { System.out.println("1"); }
void function1() { System.out.println("1"); }
} class Class2 extends Class1 { } class Class3 extends Class2 {
void function5() { System.out.println("3"); }
void function2() { System.out.println("3"); }
} class Class4 extends Class3 {
void function4() { System.out.println("4"); }
void function5() { System.out.println("4"); }
} class Class5 extends Class3 {
void function5() { System.out.println("5"); }
} void test() {
new Class3().function4();
new Class5().function2();
new Class4().function5();
new Class1().function3();
}

Some of the tests in the raw problem package have been removed due to the "Maximal summary testset file size exceeded" error on Codeforces.

题意:

题面说的很复杂,但是我们可以将他转换成一个比较直白的模型:

给你n个点,依此输入n-1条边,形成一棵树。然后依此输入n行,依此表示1-n这几个点每个点含有哪几个值(一个点可以包含多个值,也可以不包含值,如果一条路径上,后面的点包含的值如果和前面点包含的值相同,在询问时会覆盖前面的),然后q个询问,每个询问输入两个值:u,r;询问u到根节点路径上哪个点包含r这个值(相同的值后面点覆盖前面点),输出这个点的坐标。

思路:

我们对每个值建一棵树,将包含这些值的点存进树里,点i就将树上点i标为i,然后询问u,r时,我们只要询问第r棵树上1-u上最大值就好了(用个链剖+线段树就好了),建树的话直接动态开点就行了不会超内存,这样的话这道题就很好写了。。

如果想到了思路就很好写,之前想歪了思路,debug了半天都没有得到想要的值。

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int Max = 3e7+;
const int M = 2e6+;
const int MM = 2e6;
int ls[Max],rs[Max],sum[Max],root[Max],idx,ed[Max];
struct node{
int to,next;
}e[M];
int cnt,cnt1,n;
int son[M],siz[M],head[M],fa[M],top[M],dep[M],tid[M],mx[M],rk[M];
void add(int u,int v){
e[++cnt].to = v;e[cnt].next = head[u];head[u] = cnt;
} void dfs1(int u,int faz,int deep){
dep[u] = deep;
fa[u] = faz;
siz[u] = ;
for(int i = head[u];i;i = e[i].next){
int v = e[i].to;
if(v == faz) continue;
dfs1(v,u,deep+);
siz[u] += siz[v];
if(siz[v] > siz[son[u]]||son[u] == -)
son[u] = v;
}
} void dfs2(int u,int t){
top[u] = t;
mx[u] = cnt1;
tid[u] = cnt1;
rk[cnt1] = u;
cnt1++;
if(son[u] == -) return ;
dfs2(son[u],t),mx[u] = max(mx[u],mx[son[u]]);
for(int i = head[u];i;i=e[i].next){
int v = e[i].to;
if(v != fa[u]&&v != son[u])
dfs2(v,v),mx[u] = max(mx[u],mx[v]);
}
} void update(int &k,int l,int r,int p,int num){
if(!k){
k = ++idx;
sum[k] = num;
}
sum[k] = max(sum[k],num);
if(l == r)
return ;
int m = (l + r) >> ;
if(p <= m) update(ls[k],l,m,p,num);
else update(rs[k],m+,r,p,num);
} int query(int k,int L,int R,int l,int r){
if(!k) return ;
if(L <= l&&R >= r){
return sum[k];
}
int m = (l + r) >> ;
int ans = ;
if(L <= m) ans = max(ans,query(ls[k],L,R,l,m));
if(R > m) ans = max(ans,query(rs[k],L,R,m+,r));
return ans;
} int solve(int x,int y,int rt){
int fx = top[x],fy = top[y];
int ans = ;
while(fx != fy){
if(dep[fx] < dep[fy]) swap(x,y),swap(fx,fy);
ans = max(ans,query(root[rt],tid[fx],tid[x],,MM));
x = fa[fx]; fx = top[x];
}
if(dep[x] > dep[y]) swap(x,y);
ans = max(ans,query(root[rt],tid[x],tid[y],,MM));
return ans;
} int main()
{
int x,k,q,t,n;
idx = ;
cnt1 = ; cnt = ;
root[] = ,sum[] = ;
scanf("%d",&n);
memset(son,-,sizeof(son));
for(int i = ;i <= n;i ++){
scanf("%d",&x);
add(x,i); add(i,x);
}
dfs1(,,); dfs2(,);
for(int i = ;i <= n;i ++){
scanf("%d",&t);
for(int j = ;j <= t;j ++){
scanf("%d",&x);
update(root[x],,MM,tid[i],i);
}
}
scanf("%d",&q);
while(q--){
scanf("%d %d",&k,&x);
//cout<<"kk: "<<k<<" "<<root[k]<<endl;
int num = solve(,k,x);
if(num == ) num = -;
printf("%d\n",num);
}
return ;
}

Gym - 101848C Object-Oriented Programming (树链剖分+线段树+动态开点)的更多相关文章

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  2. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  3. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  4. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  5. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  6. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  7. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  8. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  9. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  10. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

随机推荐

  1. 用commander.js构建自己的脚手架工具

    随着前端技术的发展,工程化逐渐成为了一种趋势.但在实际开发时,搭建项目是一件很繁琐的事情,尤其是在对一个框架的用法还不熟悉的时候.于是很多框架都自带一套脚手架工具,在初始化前端项目的时候就可以不用自己 ...

  2. H5 16-并集选择器

    16-并集选择器 我是标题 我是段落 我是段落 我是段落 <!DOCTYPE html> <html lang="en"> <head> < ...

  3. JS 执行上下文

    先看个小例子 function fn(){ console.log(a);//undefined; var a = 1; } fn(); 为什么打印出来的是 undefined 呢? 执行上下文概念 ...

  4. Spring MVC普通类或工具类中调用service报空空指针的解决办法(调用service报java.lang.NullPointerException)

    当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.la ...

  5. 本地项目托管到github上

    一,步骤 1.在github上新建一个仓库 2.进入我的项目目录, git init //初始化本地仓库 3.git add . //把修改的代码提交到暂存区 4.git status 该命令会把你本 ...

  6. #Leetcode# 989. Add to Array-Form of Integer

    https://leetcode.com/problems/add-to-array-form-of-integer/ For a non-negative integer X, the array- ...

  7. 阿里云ECS服务器云监控(cloudmonitor)Go语言版本插件安装卸载与维护

    云监控Go语言版本插件安装_主机监控_用户指南_云监控-阿里云https://help.aliyun.com/document_detail/97929.html 云监控cloudmonitor 1. ...

  8. JEECG 3.7 Memory Leak

    JEECG 3.7 版本常见问题贴 - JEECG官方网站-企业级JAVA快速开发平台 - Powered by Discuz!http://www.jeecg.org/forum.php?mod=v ...

  9. day 7-6 GIL,死锁,递归锁与信号量,Event,queue,

    摘要: 1.死锁与递归锁 2.信号量 3.Event 4.Timer 5.GIL 6.Queue 7.什么时候该用多线程和多进程 一. 死锁与递归锁 所谓死锁: 是指两个或两个以上的进程或线程在执行过 ...

  10. vue-cli3.0之vue.config.js的配置项(注解)

    module.exports = { // 部署应用时的基本 URL baseUrl: process.env.NODE_ENV === 'production' ? '192.168.60.110: ...