[CODE FESTIVAL 2017]Full Tournament
题意:$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的更多相关文章
- @atcoder - CODE FESTIVAL 2017 Elimination Tournament Round 3 F@ Unicyclic Graph Counting
目录 @description@ @solution@ @accpeted code@ @details@ @description@ 求有多少 n 点 n 边的无向连通图,满足第 i 个点的度数为 ...
- 【赛时总结】 ◇赛时·IV◇ CODE FESTIVAL 2017 Final
◇赛时-IV◇ CODE FESTIVAL 2017 Final □唠叨□ ①--浓浓的 Festival 气氛 ②看到这个比赛比较特别,我就看了一看--看到粉粉的界面突然开心,所以就做了一下 `(* ...
- CODE FESTIVAL 2017 qual B B - Problem Set【水题,stl map】
CODE FESTIVAL 2017 qual B B - Problem Set 确实水题,但当时没想到map,用sort后逐个比较解决的,感觉麻烦些,虽然效率高很多.map确实好写点. 用map: ...
- CODE FESTIVAL 2017 qual B C - 3 Steps【二分图】
CODE FESTIVAL 2017 qual B C - 3 Steps 题意:给定一个n个结点m条边的无向图,若两点间走三步可以到,那么两点间可以直接连一条边,已经有边的不能连,问一共最多能连多少 ...
- [AtCoder Code Festival 2017 QualB D/At3575] 101 to 010 - dp
[Atcoder Code Festival 2017 QualB/At3575] 101 to 010 有一个01序列,每次可以选出一个101,使其变成010,问最优策略下能操作几次? 考虑像 11 ...
- CODE FESTIVAL 2017 qual B
昨晚因为有点事就去忙了,没打后悔啊 A - XXFESTIVAL Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem ...
- 【AtCoder】CODE FESTIVAL 2017 Final
A - AKIBA 模拟即可 代码 #include <bits/stdc++.h> #define fi first #define se second #define pii pair ...
- 【题解】Popping Balls AtCoder Code Festival 2017 qual B E 组合计数
蒟蒻__stdcall终于更新博客辣~ 一下午+一晚上=一道计数题QAQ 为什么计数题都这么玄学啊QAQ Prelude 题目链接:这里是传送门= ̄ω ̄= 下面我将分几个步骤讲一下这个题的做法,大家不 ...
- AtCoder Code Festival 2017 Team Relay J - Indifferent
题目大意:共$2n$个价格$p_i$.两人轮流取.你每次取最大的,对方每次随机取.问你取的期望和是多少. 题解:从小到大排序,$\sum\limits_{i=0}^{2n-1} \frac{i*p_i ...
随机推荐
- HTML5获取地理位置信息并在Google Maps上显示
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- shell 文件内容替换 sed用法
sed 's/要被替换的字符串/新的字符串/g' sed 's/test/mytest/g' example-----在整行范围内把test替换为mytest. 如果没有g标记,则只有每行第一个匹配的 ...
- php中的__call()函数重载
<?php #调用类中没有的方法时, 会自动调用__call方法重载 #第一个参数是调用时的方法名, 第二个参数为参数组成的数组 class Cat{ public function Hello ...
- 任务调度框架kunka
kunka kunka是一个任务调度框架.用户只需要在Task接口中实现自己要执行的功能,并且选择合适的执行器,放入TaskManager中,就可以了完成整个任务了. 实现细节 整个任务信息存放在内存 ...
- Python3 Socket和SocketServer 网络编程
socket只能实现同时一个服务和一个客户端实现交互,socketserver可以实现多个客户端同时和服务端交互 1.利用Socket编写简单的同一个端口容许多次会话的小案例: 服务端: #!/usr ...
- linux驱动基础系列--Linux下Spi接口Wifi驱动分析
前言 本文纯粹的纸上谈兵,我并未在实际开发过程中遇到需要编写或调试这类驱动的时候,本文仅仅是根据源码分析后的记录!基于内核版本:2.6.35.6 .主要是想对spi接口的wifi驱动框架有一个整体的把 ...
- java===java基础学习(6)---流程控制,for,if,switch,continue,break
注意点: for循环的用法和python截然不同,注意格式 switch~,switch对应的case每当执行完毕都要break,由于基本不怎么用switch,所以作为了解. 中断流程控制语句,请考虑 ...
- c++设计模式系列----factory模式
问题: 假设我们要开发一个游戏--打怪物,首先,游戏有分等级,假设有初级,中级两个个等级(就不用flappy bird模式了,那个比较特殊,对一个玩家来说是难以具有持久吸引力的!),不同的等级怪物也是 ...
- 【bzoj4486】【JSOI2015】串分割
老省选题了. 首先考虑怎么比较超长数字的大小? 参见UTR1的那道题 先比size,然后比较字典序即可. 接下来考虑下切割的问题. 因为要将字符串切割成k份,所以这个字符串只会存在n/k个本质不同的起 ...
- VPS性能测试方法小结(8)
1.为了能够得到更为准确和详细的有关VPS主机性能测试数据,我们应该多角度.全方位地运行多种VPS性能测试工具来进行检测,同时也要记得排除因本地网络环境而造成的数据结果的错误. 2.VPS主机性能跑分 ...