【CF878C】Tournament

题意:有k个项目,n个运动员,第i个运动员的第j个项目的能力值为aij。一场比赛可以通过如下方式进行:

每次选出2个人和一个项目,该项目能力值高者获胜,败者被淘汰,胜者继续比赛。最后一个人是冠军。

在一场比赛中,你可以任意安排比赛顺序,任意选择每次的参赛者和项目,现在想知道的是有多少人可能成为最后的冠军。

为了加大难度,一共有n次询问,第i次询问是前i个人进行比赛,问最终由多少人可能成为总冠军。

n<=50000,k<=10,aij<=10^9

题解:只要敢想就去写吧。

我们将所有人看成一张n个点的有向图,如果i的某项能力值比j高,则从i到j连一条有向边。我们将得到的整个图中的强连通分量缩成点,那么最终得到的一定是一条链。其中每个强联通分量中每一项的最小值都比下一个强联通分量的最大值还大。然后我们依次加入每个点,考虑如何维护这条链。

在加入第i个人时,对于每个项目,我们可以在set中找到这个人的前驱和后继,并记录二者在链中的位置。令a为每个项目中前驱位置的最大值,b为每个项目中后继位置的最小值,如果a>b,则说明i能打过a,b能打过i,并且a能打过b,出现了一个环!我们将这个环暴力缩掉即可;如果a=b,我们将i加入到a的强联通分量即可;如果a<b,那么a=b-1,我们把i加到ab中间即可。

可以用并查集维护连通性,链表维护整条链。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>
#include <utility>
#define mp(A,B) make_pair(A,B)
using namespace std;
const int maxn=50010;
int n,m,last;
int f[maxn],mx[maxn][11],mn[maxn][11],siz[maxn],nxt[maxn],v[11]; set<pair<int,int> > s[11];
set<pair<int,int> >::iterator it; inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int find(int x)
{
return (f[x]==x)?x:(f[x]=find(f[x]));
}
inline void merge(int a,int b)
{
for(int i=1;i<=m;i++) mx[b][i]=max(mx[b][i],mx[a][i]),mn[b][i]=min(mn[b][i],mn[a][i]);
siz[b]+=siz[a],f[a]=b;
}
int main()
{
n=rd(),m=rd();
int i,j,a,b,t;
for(j=1;j<=m;j++) s[j].insert(mp(mx[1][j]=mn[1][j]=rd(),1));
f[1]=siz[1]=last=1;
puts("1");
for(i=2;i<=n;i++)
{
a=b=0;
for(j=1;j<=m;j++)
{
v[j]=rd();
it=s[j].upper_bound(mp(v[j],i));
if(it!=s[j].end())
{
t=find((*it).second);
if(!b||mx[t][j]<mx[b][j]) b=t;
}
if(it!=s[j].begin())
{
it--,t=find((*it).second);
if(!a||mx[t][j]>mx[a][j]) a=t;
}
s[j].insert(mp(v[j],i));
}
f[i]=i,siz[i]=1;
for(j=1;j<=m;j++) mx[i][j]=mn[i][j]=v[j];
if(!a) nxt[i]=b;
else if(!b) last=i,nxt[a]=i;
else if(a==b) merge(i,a);
else if(mx[a][1]<mx[b][1]) nxt[a]=i,nxt[i]=b;
else
{
for(t=b;t!=a;t=nxt[t],merge(t,b));
merge(i,b);
nxt[b]=nxt[a];
if(a==last) last=b;
}
printf("%d\n",siz[last]);
}
return 0;
}

【CF878C】Tournament set+并查集+链表的更多相关文章

  1. Codeforces #541 (Div2) - F. Asya And Kittens(并查集+链表)

    Problem   Codeforces #541 (Div2) - F. Asya And Kittens Time Limit: 2000 mSec Problem Description Inp ...

  2. CodeForces 566D Restructuring Company (并查集+链表)

    题意:给定 3 种操作, 第一种 1 u v 把 u 和 v 合并 第二种 2 l r 把 l - r 这一段区间合并 第三种 3 u v 判断 u 和 v 是不是在同一集合中. 析:很容易知道是用并 ...

  3. CodeForces - 357C Knight Tournament 伪并查集(区间合并)

    Knight Tournament Hooray! Berl II, the king of Berland is making a knight tournament. The king has a ...

  4. 100: cf 878C set+并查集+链表

    $des$Berland要举行 $n$ 次锦标赛,第一次只有一个人,之后每一次会新加入一个人.锦标赛中有 $k$ 种运动项目,每个人在这 $k$ 种项目上都有一个能力值,每次会选择任意两个还未被淘汰的 ...

  5. 稀疏图(邻接链表),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)

    全部函数通过杭电 1142,1162,1198,1213等题目测试. #include<iostream> #include<vector> #include<queue ...

  6. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 828C) - 链表 - 并查集

    Ivan had string s consisting of small English letters. However, his friend Julia decided to make fun ...

  7. cf-Round541-Div2-F(并查集+静态链表)

    题目链接:http://codeforces.com/contest/1131/problem/F 思路: 很容易看出这是一道并查集的题目,因为要输出每个cage中住的鸟的编号,故采用静态链表.用l[ ...

  8. Codeforces 1131 F. Asya And Kittens-双向链表(模拟或者STL list)+并查集(或者STL list的splice()函数)-对不起,我太菜了。。。 (Codeforces Round #541 (Div. 2))

    F. Asya And Kittens time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

随机推荐

  1. Linux下修改MySql的root密码

    linux下如何修改Mysql的root密码     今天,忘了mysql下的root密码,想重置一下,但找了多个网站上的方法均有问题,最后参考几家的过程,经过不断尝试获得,终于成功了,下面特将过程分 ...

  2. django test模块

    今天试了试django自带的test模块,断点执行到一下代码中时发现一点儿小问题: def _create_test_db(self, verbosity, autoclobber): "& ...

  3. Unity&C# Time时间相关

    1.Unity Time类 1/ Time.time 表示从游戏开发到现在的时间,会随着游戏的暂停而停止计算. 2/ Time.timeSinceLevelLoad 表示从当前Scene开始到目前为止 ...

  4. SPOJ QTREE5 lct

    题目链接 对于每一个节点,记录这个节点所在链的信息: ls:(链的上端点)距离链内部近期的白点距离 rs:(链的下端点)距离链内部近期的白点距离 注意以上都是实边 虚边的信息用一个set维护. set ...

  5. [AX]AX2012 R2 采购订单的“Request change”

    在采购订单List或者Detail窗口的操作面板上有一个叫做“Request change”的按钮,如果这个按钮是激活的,采购订单不能直接编辑,而必须先使用这个按钮请求修改后,采购订单才能进入编辑状态 ...

  6. 【Android】Android中如何取消调转界面后EditText默认获取聚焦问题

    参考资料: https://www.cnblogs.com/dream-cichan/p/aaaa.html http://blog.csdn.net/u013703461/article/detai ...

  7. /var/spool/postfix/maildrop/ 中有大量的文件

    今天查看硬盘剩余的容量,发现‘/’目录下占用了大量的空间:可我在这个目录下面没有放什么东西:仔细查看在/var/spool/postfix/maildrop/ 中发现了大量的文件.怎么会有这么多的文件 ...

  8. Vim 的 Python 编辑器详细配置过程 (Based on Ubuntu 12.04 LTS)

    为什么要用vim编辑py文件? 因为在Linux命令行中,缺少图形界面的IDE,vim是最佳的文本编辑器,而为了更好的编辑py文本,所以配置vim. 1. 安装完整版vim vi和vim的区别? 在L ...

  9. TCPdump指定时间或者指定大小进行循环抓取报文

    背景:我们用tcpdump工具循环抓取网卡上的报文,我们会遇到如下情况: 1. 抓取报文后隔指定的时间保存一次: 2. 抓取报文后达到指定的大小保存一次: 本文就这两种情况给出tcpdump的使用方法 ...

  10. 【Linux】将终端的命令输出保存为txt文本文件

    Linux中的终端很方便,可以直接复制粘贴的. 之后开一个gedit文本编辑器,把复制到的内容粘贴就可以的. 不像windows的cmd控制台,需要先右键标题栏,选择编辑->全选/标记,在右键标 ...