Description

  

  有\(n\)(\(1 \le n \le 400\))只鸡,接下来按顺序进行\(m\)(\(1 \le m \le 10^5\))次操作。每次操作涉及两只鸡,如果都存在则随意拿走一只;如果只有一只存在,拿走这一只;如果都不存在,什么都不做。

  

  求最后有多少对鸡(无序)可能共同存活。

  

  

  

Solution

  

  个人认为单用集合的解释方法有失偏颇。

  

  首先考虑枚举两只鸡,规定它们一定要存活,然后模拟过程。怎么看单次模拟的复杂度都不会小于\(m\),因此要第一时间舍弃这种方法。

  

  于是要换个角度考虑。我们看看能不能算出某一只鸡存活的条件,再枚举两只鸡,并判断它们的条件是否冲突。

  

  假设我们令\(a\)必须存活。

  

  先看那些与\(a\)有关的操作:显然,另一只鸡在该操作前必须存活。我们虽然得到了这个结论,但是这些操作的顺序有先后影响,并不好考虑。

  

  为了消除后效性,我们从后往前考虑每个事件。如果遇到与\(a\)有关的事件\((a,b)\),我们必须令\(b\)在这个时刻前存活。这意味着下次遇到与\(a\)或\(b\)有关的事件,我们必须令另一者在这个时刻前存活。我们记如果"\(a\)必须存活",当前所有必须存活的鸡组成的集合为\(S\),则形式化地讲:

  

  初始时,\(S\)里只有\(a\)

  

  1.如果遇到一个事件,其中一者属于\(S\),则另一者必须在这个时刻前存活。我们将另一者加进\(S\)

  

  2.如果两者都属于\(S\),则必须死一个。这立刻违反了\(S\)的定义,因此\(a\)不可能存活。我们将其纳入统计答案的考虑对象

  

  3.如果两者都不属于\(S\),由于我们从后往前考虑,即使这两者在更早的时间与\(a\)的生死有关,但那个有关的时刻结束之后,这两者的生死并不重要。因此这个事件不需要纳入考虑范围。

  

  由此,扫完全部事件之后,依赖存活关系可以形象为一棵内向树(上述1.发生时,从另一者向属于\(S\)的一者连一条有向边),我们不再将其看做集合考虑,因为那无法解释接下来的事情。我们称它为\(a\)的存活树。

  

  \(a\)的存活树的每一条边都代表着一次依赖事件,每一次事件的成功与否都决定了\(a\)能否存活。事件发生的具体顺序我们不需要知道,但是一定是按照从叶子节点向上的某个拓扑序发生的。

  

  考虑两只鸡\(a\)和\(b\)能否存活。有了存活树的概念,却无从下手?先从简单的一面看:如果二者的存活树的点集无交,那么显然没有影响,二者可以共存。关键是如果有交,可以共存吗?

  

  对于一个点\(x\),其在\(a\)和\(b\)的存活树中都出现。如果\(x\)在两棵树中的父亲不同,这代表着两次不同的事件,先后发生,却都依赖于\(x\)。则后发生的一者必然不能保证\(x\)存活,因此\(a\)和\(b\)有一个必须死。如果\(x\)在两棵树中的父亲相同,首先二者不可能是两个事件,不然二者自身都不可能存活,不在考虑范围之内;既然是同一个事件,那么它们在这一步的确共存,因为它们共同进行了有益的一步。我们会发现,两棵树中可能出现一些“共同链”,但这并不意味着二者可以共存。因为两棵树的根一定不同,所以“共同链”的链顶一定不是根,即“共同链”的链顶一定会出现第一个情况:父亲不一样,有一只鸡必须死。

  

  由上证毕,两只鸡能共存,当且仅当存活树的点集无交集。

  

  在实现时,不需要建树,树只是用来严格证明的,我们只需要计算出每只存活的鸡的存活树点集合即可。

  

    

  

Code

  

#include <cstdio>
#include <bitset>
using namespace std;
const int N=405,M=10005;
typedef bitset<N> bs400;
int n,m;
int a[M][2];
bool die[N];
bs400 b[N];
void readData(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d",&a[i][0],&a[i][1]);
}
void calc(){
for(int i=1;i<=n;i++){
b[i][i]=1;
for(int j=m;j>=1;j--){
int u=a[j][0],v=a[j][1];
if(b[i][u]&&b[i][v]){
die[i]=true;
break;
}
else if(b[i][u])
b[i][v]=1;
else if(b[i][v])
b[i][u]=1;
}
}
}
void print(){
int ans=0;
for(int i=1;i<n;i++)
if(!die[i])
for(int j=i+1;j<=n;j++)
if(!die[j]){
if((b[i]&b[j]).none())
ans++;
}
printf("%d\n",ans);
}
int main(){
readData();
calc();
print();
return 0;
}

【AGC016E】Poor Turkeys的更多相关文章

  1. [AGC016E]Poor Turkeys

    [AGC016E]Poor Turkeys 题目大意: 有\(n(n\le400)\)只火鸡,编号为\(1\)到\(n\),有\(m(m\le10^5)\)个人,每人指定了两只火鸡\(x\)和\(y\ ...

  2. 【故障处理】队列等待之enq IV - contention案例

    [故障处理]队列等待之enq IV -  contention案例 1.1  BLOG文档结构图 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也 ...

  3. 【转】Java HashMap 源码解析(好文章)

    ­ .fluid-width-video-wrapper { width: 100%; position: relative; padding: 0; } .fluid-width-video-wra ...

  4. 【POJ1113】Wall(凸包)

    [题目] Description Once upon a time there was a greedy King who ordered his chief Architect to build a ...

  5. 【POJ3481】【splay】Double Queue

    Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest ...

  6. 【POJ2985】【Treap + 并查集】The k-th Largest Group

    Description Newman likes playing with cats. He possesses lots of cats in his home. Because the numbe ...

  7. 【BZOJ1926】粟粟的书架(主席树,前缀和)

    [BZOJ1926]粟粟的书架(主席树,前缀和) 题面 Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co ...

  8. 【BZOJ1205】[HNOI2005]星际贸易(动态规划)

    [BZOJ1205][HNOI2005]星际贸易(动态规划) 题面 BZOJ 洛谷 题解 第一问就是一个裸\(dp\),因为什么都不用考虑... 所以设\(f[i][j]\)表示当前停靠在第\(i\) ...

  9. 【hdu3080】01背包(容量10^7)

    [题意]n个物品,有wi和vi,组成若干个联通块,只能选取一个联通块,问得到m的价值时最小要多少空间(v).n<=50,v<=10^7 [题解] 先用并查集找出各个联通块. 这题主要就是v ...

随机推荐

  1. C# 枚举基本用法及扩展方法

    没什么好说的,都是些基础! 代码如下: using System; using System.Collections.Generic; using System.ComponentModel; usi ...

  2. NOIP2018题解

    Preface 联赛结束后趁着自己还没有一下子把题目忘光,所以趁机改一下题目. 没有和游记一起写主要是怕篇幅太长不美观. 因此这里我们直接讲题目,关于NOIP2018的一些心得和有趣的事详见:NOIP ...

  3. 【php增删改查实例】第十五节 - 用户管理模块(删除确认)

    假如有一天,用户找到你,说万一不小心手一抖,就点击了删除用户,不太好.能不能再误点的时候,再给个确认框,让用户进行二次确认. OK,用户是上帝.这边我们可以考虑用confirm方法进行开发. 参考代码 ...

  4. 2011 noip 提高组

    首先吐槽:刚刚写着写着突然蓝屏了,,emmm,写到最后一题了蓝屏了. 当时我的内心是崩溃的. 然后,旁边的大佬默默来了一句:论保存草稿的重要性. 连着蓝了三次之后开了防火墙,然后,,我左边那位同学又开 ...

  5. 阿里云centos内docker的搭建

    由于docker在17之后的版本分成了docker EE(企业版)和docker CE(社区版),那么我们在安装的时候就要开始纠结的选择了,这里我推荐了docker CE(社区版). 实际上这两个版本 ...

  6. win8系统本地服务网络受限cpu占用率过高解决方案

    今天更新软件时突然就打不开软件了,接着cpu就飙升. 打开任务管理器看到是“本地服务网络受限”这么一个东西占用的cpu最高. 在网上找到的解决方案无效的: 1.关闭家庭组(服务里的homegroup· ...

  7. Openstack架构概念图-简单汇总

    OpenStack是一个云平台管理的项目,它不是一个软件.这个项目由几个主要的组件组合起来完成一些具体的工作.想要了解openstack,第一步我们可以观察他的概念图: 针对上图的翻译+解释: 上图主 ...

  8. 忘记mysql数据库root密码

    找到配置文件my.ini  ,然后将其打开,可以选择用记事本打开,查找的方法如下: 打开后,搜索mysqld关键字 找到后,在mysqld下面添加skip-grant-tables,保存退出. PS: ...

  9. 【CV】ICCV2015_Learning Temporal Embeddings for Complex Video Analysis

    Learning Temporal Embeddings for Complex Video Analysis Note here: it's a review note on novel work ...

  10. java注解的简单介绍

    什么是注解 1.注解就是Annontation,Annontation是Java5开始引入的新特征,中文名称叫做注解,它提供了一种安全的类似注释的机制,可以起到减少配置的成果,给程序起到辅助性的作用 ...