题意:$2^n$个编号为$1\cdots2^n$的人打比赛,这个比赛会给每个人一个唯一的排名,比赛规则递归地定义如下:

$2^n$个人打的是级别为$n$的比赛,初始时他们按某种顺序站成一排

当$n=0$,唯一的一人是第一名

当$n\geq1$,每相邻两个人PK,编号小的人获胜,让$2^{n-1}$个胜者按在原序列中的相对顺序进行级别为$n-1$的比赛,让$2^{n-1}$个败者按在原序列中的相对顺序进行级别为$n-1$的比赛,并将他们的排名加上$2^{n-1}$

可以看出如果初始时的顺序确定了,这样一定可以给所有人一个唯一的排名

题意不是特别易懂,上图描述了一个打比赛的过程

现在给定一份最终每个人的排名,有一些人的排名还未确定,让你构造一个初始序列使得最终排名和输入相符

以下用从$0$开始的下标和排名

首先,我们可以通过合理安排顺序,使得每次PK都是左边的人赢,考虑把打比赛的过程倒序,那么两个在$n-1$级比赛中排名都为$i$的人会进行一次PK,胜者在$n$级比赛中的排名为$2i$,败者为$2i+1$

然后有一个判定是否有解的结论:如果在一场级别为$n$的比赛中第$i$名的人是$a_i$,那么$a_i\lt a_{i+2^j}(i\&2^j=0,0\leq j\lt n)$

考虑用归纳法证明:当$j=0$时显然成立(这是许多场$1$级比赛),设当$j\lt n-1$时结论成立

若$i=2k$,那么$i$是两个在$n-1$级比赛中排名都为$k$的人之间的PK胜者,$i+2^{n-1}$是两个在$n-1$级比赛中排名都为$k+2^{n-2}$的人之间的PK胜者,因为两个$n-1$级比赛中都有$a_k\lt a_{k+2^{n-2}}$,所以$i$是四个人中最强的,也就是说$a_i\lt a_{i+2^{n-1}}$

若$i=2k+1$,类似可得$i+2^{n-1}$是最弱的,所以结论成立

有了这个结论,问题转为:给定一个DAG$i\rightarrow i+2^j(i\&2^j=0)$和部分节点的权值$a_i$,填上剩下的权值使其满足限制$i\rightarrow j,a_i\lt a_j$

首先正反各扫一遍,得到每个节点的权值的取值范围,这是一个区间

直接贪心即可,从小到大依次填数,填$x$时选择未被选择的区间中满足$L\leq x$且有最小$R$的区间,这个直接按$L$从小到大加入区间,用优先队列维护$R$即可

因为每次都是左边的人赢,即按奇偶性分开,所以最后要像FFT一样把$i$的权值放到$rev_i$去

这个题好神啊...

#include<stdio.h>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
int a[262144],rev[262144],lw[262144],hi[262144],val[262144];
struct pr{
	int x,y;
	pr(int a=0,int b=0){x=a;y=b;}
};
bool operator<(pr a,pr b){return a.x==b.x?a.y>b.y:a.x>b.x;}
priority_queue<pr>q;
vector<pr>e[262144];
int main(){
	int n,N,i,j;
	scanf("%d",&n);
	N=1<<n;
	for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(n-1));
	for(i=0;i<N;i++){
		scanf("%d",a+i);
		a[i]--;
	}
	for(i=N-1;i>=0;i--){
		hi[i]=~a[i]?a[i]:N-1;
		for(j=0;j<n;j++){
			if(~i>>j&1)hi[i]=min(hi[i],hi[i|(1<<j)]);
		}
	}
	for(i=0;i<N;i++){
		lw[i]=~a[i]?a[i]:0;
		for(j=0;j<n;j++){
			if(i>>j&1)lw[i]=max(lw[i],lw[i^(1<<j)]);
		}
	}
	for(i=0;i<N;i++){
		if(lw[i]>hi[i]){
			puts("NO");
			return 0;
		}
		e[lw[i]].push_back(pr(hi[i],i));
	}
	for(i=0;i<N;i++){
		for(pr t:e[i])q.push(t);
		if(q.empty()||q.top().x<i){
			puts("NO");
			return 0;
		}
		val[q.top().y]=i;
		q.pop();
	}
	puts("YES");
	for(i=0;i<N;i++)printf("%d ",val[rev[i]]+1);
}

[CODE FESTIVAL 2017]Full Tournament的更多相关文章

  1. @atcoder - CODE FESTIVAL 2017 Elimination Tournament Round 3 F@ Unicyclic Graph Counting

    目录 @description@ @solution@ @accpeted code@ @details@ @description@ 求有多少 n 点 n 边的无向连通图,满足第 i 个点的度数为 ...

  2. 【赛时总结】 ◇赛时·IV◇ CODE FESTIVAL 2017 Final

    ◇赛时-IV◇ CODE FESTIVAL 2017 Final □唠叨□ ①--浓浓的 Festival 气氛 ②看到这个比赛比较特别,我就看了一看--看到粉粉的界面突然开心,所以就做了一下 `(* ...

  3. CODE FESTIVAL 2017 qual B B - Problem Set【水题,stl map】

    CODE FESTIVAL 2017 qual B B - Problem Set 确实水题,但当时没想到map,用sort后逐个比较解决的,感觉麻烦些,虽然效率高很多.map确实好写点. 用map: ...

  4. CODE FESTIVAL 2017 qual B C - 3 Steps【二分图】

    CODE FESTIVAL 2017 qual B C - 3 Steps 题意:给定一个n个结点m条边的无向图,若两点间走三步可以到,那么两点间可以直接连一条边,已经有边的不能连,问一共最多能连多少 ...

  5. [AtCoder Code Festival 2017 QualB D/At3575] 101 to 010 - dp

    [Atcoder Code Festival 2017 QualB/At3575] 101 to 010 有一个01序列,每次可以选出一个101,使其变成010,问最优策略下能操作几次? 考虑像 11 ...

  6. CODE FESTIVAL 2017 qual B

    昨晚因为有点事就去忙了,没打后悔啊 A - XXFESTIVAL Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem ...

  7. 【AtCoder】CODE FESTIVAL 2017 Final

    A - AKIBA 模拟即可 代码 #include <bits/stdc++.h> #define fi first #define se second #define pii pair ...

  8. 【题解】Popping Balls AtCoder Code Festival 2017 qual B E 组合计数

    蒟蒻__stdcall终于更新博客辣~ 一下午+一晚上=一道计数题QAQ 为什么计数题都这么玄学啊QAQ Prelude 题目链接:这里是传送门= ̄ω ̄= 下面我将分几个步骤讲一下这个题的做法,大家不 ...

  9. AtCoder Code Festival 2017 Team Relay J - Indifferent

    题目大意:共$2n$个价格$p_i$.两人轮流取.你每次取最大的,对方每次随机取.问你取的期望和是多少. 题解:从小到大排序,$\sum\limits_{i=0}^{2n-1} \frac{i*p_i ...

随机推荐

  1. 4、什么是事务?MySQL如何支持事务?

    什么是事务? 事务是由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行.程序和事务是两个不同的概念.一般而言:一段程序中可能包含多个事务.(说白了就是几步的数据库操作 ...

  2. hdu 1200 To and Fro(简单模拟或DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1200 To and Fro Time Limit: 2000/1000 MS (Java/Others ...

  3. 用例图(Use Case Diagram)

    用例图(Use Case Diagram) 执行者/参与者(Actor): 表示与您的应用程序或系统进行交互的用户.组织或外部系统.用一个小人表示. 用例(Use Case): 即系统具有的功能,在用 ...

  4. 随机森林(Random Forest)详解(转)

    来源: Poll的笔记 cnblogs.com/maybe2030/p/4585705.html 1 什么是随机森林?   作为新兴起的.高度灵活的一种机器学习算法,随机森林(Random Fores ...

  5. LCD实验学习笔记(八):中断

    s3c2440有60个中断源(其中15个为子中断源). 31个32位的通用寄存器,6个程序状态寄存器.有6种工作模式(系统/用户模式,快中断模式,管理模式,数据访问中止模式,中断模式,未定指令中止模式 ...

  6. 在Github里集成Readthedocs服务

    Readthedocs支持Markdown格式和sphinx格式的文档排版,是部署项目文档的绝佳平台.利用Github的托管服务,我们可以方便地将文档托管于Github,并利用Readthedocs查 ...

  7. JavaScript里的小妖精

    JavaScript里的小妖精———this!! 关于this指向这个问题,活生生折磨了我一个下午,回来静下心捋顺一下,总结出来一下规律. 当然,this这个复杂的问题不是一句两句可以说清楚,作为菜鸟 ...

  8. zookeeper安装和搭建集群方式(window)

    1.   概述 ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.名字服务.分布式同步.组服务等.ZooKeeper的目标就是封装好复杂 ...

  9. [转]nginx启动期都做了哪些事

    nginx是个多进程web容器,不同的配置下它的启动方式也是不同的,这里我只说说最典型的启动方式. 它有1个master进程,和多个worker进程(最优配置的数量与CPU核数相关).那么,首先我们要 ...

  10. HDU-5360

    Hiking Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Su ...