原题网址:https://open.kattis.com/problems/boxes

Boxes

There are N boxes, indexed by a number from 1 to N.Each box may (or not may not) be put into other boxes. These boxes together form a tree structure (or a forest structure, to be precise).

You have to answer a series of queries of the following form: given a list of indices of the boxes, find the total number of boxes that the list of boxes actually contain.

Consider, for example, the following five boxes.

Figure 1: Sample input
  • If the query is the list “1”, then the correct answer is “5”, because box 1 contains all boxes.
  • If the query is the list “4 5”, then the correct answer is “2”, for boxes 4 and 5 contain themselves and nothing else.
  • If the query is the list “3 4”, then the correct answer is “2”.
  • If the query is the list “2 3 4”, then the correct answer is “4”, since box 2 also contains box 5.
  • If the query is the list “2”, then the correct answer is “3”, because box 2 contains itself and two other boxes.

Input

The first line contains the integer N (1≤N≤200000), the number of boxes.

The second line contains N

­integers. The ith integer is either the index of the box which contains the ith box, or zero if the ith box is not contained in any other box.

The third line contains an integer Q(1≤Q≤100000), the number of queries. The following Q lines will have the following format: on each line, the first integer M (1≤M≤20) is the length of the list of boxes in this query, then M integers follow, representing the indices of the boxes.

Output

For each query, output a line which contains an integer representing the total number of boxes.

Sample Input 1              

   Sample Output 1

5

0 1 1 2 2

5

1 1

2 4 5

2 3 4

3 2 3 4

1 2

5

2

2

4

3

Author(s): Chan Pak Hay

Source: Hong Kong Regional Online Preliminary 2016

题意:n个箱子,其中一些箱子装在另一些里面。Q次询问,每次给定m个箱子,问这m个箱子里面一共包含了几个箱子(包括m个箱子本身)。

建树,若第i个箱子装在第j个箱子里面,j为i的父节点。

箱子编号1~n, 箱子组成树或者森林结构,确定一个根节点0,这样箱子组成的森林就合成一棵根节点为0的树。

从根节点0开始DFS遍历整个树, 记录每个节点DFS到的顺序编号DFN[i].

tot[i]表示箱子i包含的箱子总数(包括箱子i本身)。

每个箱子包含的箱子的集合在DFS遍历的顺序下是连续的。

range[i]表示箱子i包含的箱子的DFN编号范围,即DFN编号为range[i].first~range[i].second的所有箱子都包含在箱子i里面。

举个例子,样例建树DFS遍历:

其中,range[1].first=1,range[1].second=5; DFN编号为1~5的箱子都包含在箱子1中。

range[2].first=2,range[2].second=4; DFN编号为2~4的箱子都包含在箱子4中。

range[3].first=5,range[3].second=5;  DFN编号为5的箱子包含在箱子3中。

range[4].first=3,range[4].second=3; DFN编号为3的箱子包含在箱子4中。

range[5].first=4,range[5].second=4; DFN编号为4的箱子包含在箱子5中。

得到了每个包含的箱子总数tot[i],和每个箱子i包含的箱子编号范围range[i],

对于每一组查询q,暴力枚举一遍每个箱子q[i]是否被另一个箱子包含,如果q[i]被包含,删掉q[i],最后没删掉的节点的tot求和。

#include <algorithm>
#include <cstring>
#include <string.h>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <cstdio>
#include <cmath> #define LL long long
#define N 200005
#define INF 0x3ffffff using namespace std; int n;
int belong[N]; //belong[i]表示箱子i在箱子elong[i]里面
int qnum; //查询次数
int m;
int q[];
vector<int>vec[N]; int DFN[N]; // 每个节点DFS到的顺序编号DFN[i]
pair<int,int>range[N]; //range[i]表示箱子i包含的箱子的DFN编号范围
int tot[N]; //tot[i]表示箱子i包含的箱子总数(包括箱子i本身
int pos; void dfs(int u) //DFS遍历树
{
DFN[u]=pos++;
range[u].first=pos;
tot[u]=;
for(int i=;i<vec[u].size();i++){
int v=vec[u][i];
dfs(v);
tot[u]+=tot[v];
}
range[u].second=pos;
return;
} int main()
{
while(scanf("%d",&n)!=EOF){
pos=;
memset(tot,,sizeof(tot));
for(int i=;i<=n;i++) vec[i].clear(); for(int i=;i<=n;i++)
{
scanf("%d",&belong[i]);
vec[belong[i]].push_back(i);
}
dfs(); //从根节点0开始遍历 /*
for(int i=1;i<=n;i++)
{
cout<<tot[i]<<endl;
cout<<DFN[i]<<endl;
cout<<range[i].first<<' '<<range[i].second<<endl;
}
*/ scanf("%d",&qnum);
while(qnum--)
{
scanf("%d",&m);
for(int i=;i<m;i++)
{
scanf("%d",&q[i]); //q数组为查询的箱子集合
}
int flag=; //用flag来记录哪些箱子被删掉了,如果(flag&(1<<i)),箱子q[i]就被删掉了。
for (int i=;i<m;i++) //暴力枚举每个箱子q[i],看是否包含在另一个箱子里面
{
if(!(flag&(<<i)))
{
for(int j=i+;j<m;j++)
{
if(!(flag&(<<j)))
{
if (range[q[i]].first<=range[q[j]].first && range[q[i]].second>=range[q[j]].second){ //箱子q[j]包含在箱子q[i]里面
flag|=(<<j);
}
else if (range[q[j]].first<=range[q[i]].first && range[q[j]].second>=range[q[i]].second) { //箱子q[i]包含在箱子q[j]里面
flag|=(<<i);
break;
}
}
}
}
} int ret= ;
for (int i=;i<m;i++)
{
if(!(flag&(<<i))) { //箱子q[i]没被其他箱子包含
ret+=tot[q[i]];
}
} printf("%d\n",ret);
}
}
return ;
}

2016 acm香港网络赛 B题. Boxes的更多相关文章

  1. 2016 acm香港网络赛 C题. Classrooms(贪心)

    原题网址:https://open.kattis.com/problems/classrooms Classrooms The new semester is about to begin, and ...

  2. 2016 acm香港网络赛 A题. A+B Problem (FFT)

    原题地址:https://open.kattis.com/problems/aplusb FFT代码参考kuangbin的博客:http://www.cnblogs.com/kuangbin/arch ...

  3. 2016 acm香港网络赛 F题. Crazy Driver(水题)

    原题网址:https://open.kattis.com/problems/driver Crazy Driver In the Linear City, there are N gates arra ...

  4. hihoCoder #1388 : Periodic Signal ( 2016 acm 北京网络赛 F题)

    时间限制:5000ms 单点时限:5000ms 内存限制:256MB 描述 Profess X is an expert in signal processing. He has a device w ...

  5. hdu 5881 Tea (2016 acm 青岛网络赛)

    原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=5881 Tea Time Limit: 3000/1000 MS (Java/Others)    Me ...

  6. 2015北京网络赛 G题 Boxes bfs

    Boxes Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/contest/acmicpc2015beijingonl ...

  7. HDU 5901 Count primes (2016 acm 沈阳网络赛)

    原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=5901 题意:输入n,输出n以内质数个数 模板题,模板我看不懂,只是存代码用. 官方题解链接:https ...

  8. 2013 acm 长沙网络赛 G题 素数+枚举 Goldbach

    题目 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3856 先预处理求出两个素数的和与积,然后枚举n-prime和n/pr ...

  9. 2018 ACM南京网络赛H题Set解题报告

    题目描述 给定\(n\)个数$a_i$,起初第\(i\)个数在第\(i\)个集合.有三种操作(共\(m\)次): 1 $u$ $v$ 将第$u$个数和第$v$个数所在集合合并 2 $u$ 将第$u$个 ...

随机推荐

  1. iOS用户响应者链的那些事儿

    这篇文章想跟大家分享的主旨是iOS捕获用户事件的各种情况,以及内部封装的一些特殊事件. 我们先从UIButton谈起,UIButton大家使用的太多了,他特殊的地方就在于其内置的普通Default/高 ...

  2. selenium模拟键盘操作

    单键 /** * 模拟键盘回车事件 * @throws AWTException */ public void KeyEventEnter() throws AWTException { Robot ...

  3. swoole编译安装/数据库连接池/异步mysql客户端

    一.编译安装php5.6 0.安装必要软件 http://www.cnblogs.com/itfenqing/p/6055138.html 1.下载php5.6.30 http://php.net/d ...

  4. 为php5.6.30安装redis扩展

    1.下载phpredis3.1.2 https://github.com/phpredis/phpredis/releases/tag/3.1.2 2.解压后在phpredis3.1.2目录下执行 / ...

  5. 解决log4j.xml问题http//jakarta.apache.org/log4j/ uri is not registered

    在Eclipse中,配置log4j.xml出现"http //jakarta.apache.org/log4j/ uri is not registered"的错误信息. 原始的l ...

  6. RabbitMQ三----'任务分发 '

    当有Consumer需要大量的运算时,RabbitMQ Server需要一定的分发机制来balance每个Consumer的load.试想一下,对于web application来说,在一个很多的HT ...

  7. 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记30 ScrollView Demo实战

    在上一话中我们创建了一个通过URL读取图片的Demo,这个Demo是不能拖动和缩放的.如今给它添加选项让它能够手动切换URL,并把图片加入到ScrollView中. 向Storyboard中拖入一个s ...

  8. Archlinux: 优化触摸板配置

    在逛 Archlinuxcn BBS 时看到这个帖子: fcitx 输入法看不到选词,上面键盘也不见了! 等待妹子的 依云 提到了 infinality, 并且给出了这个链接: fix-infinal ...

  9. 【BIEE】09_BIEE控制台乱码问题解决

    BIEE安装完成后,点击[启动BI服务] 接着从弹出窗口可以发现,全部汉字都是乱码 出现这种情况,想看一下BIEE启动情况是很费劲的,接着我们处理一下这个问题 1.从路径D:\obiee\user_p ...

  10. 【Shell】建立一个脚本统计当前登录用户数

    who命令 who命令是显示目前登陆系统的用户信息,执行who命令可以得知目前哪些用户登入系统,单独执行who命令会列出登入账号,使用的终端机,登入的时间以及从何处登入或正在使用哪个显示器. 统计用户 ...