Codeforces Round #443 (Div. 1) C. Tournament
C. Tournament
link
http://codeforces.com/contest/878/problem/C
description
Recently a tournament in k kinds of sports has begun in Berland. Vasya wants to make money on the bets.
The scheme of the tournament is very mysterious and not fully disclosed. Competitions are held back to back, each of them involves two sportsmen who have not left the tournament yet. Each match can be held in any of the k kinds of sport. Loser leaves the tournament. The last remaining sportsman becomes the winner. Apart of this, the scheme can be arbitrary, it is not disclosed in advance.
Vasya knows powers of sportsmen in each kind of sport. He believes that the sportsmen with higher power always wins.
The tournament is held every year, and each year one new participant joins it. In the first tournament, only one sportsman has participated, in the second there were two sportsmen, and so on. Vasya has been watching the tournament for the last n years. Help him to find the number of possible winners for each of the n tournaments.
Input
The first line contains two integers n and k (1 ≤ n ≤ 5·104, 1 ≤ k ≤ 10) — the number of tournaments and the number of kinds of sport, respectively.
Each of the next n lines contains k integers si1, si2, ..., sik (1 ≤ sij ≤ 109), where sij is the power of the i-th sportsman in the j-th kind of sport. The sportsman with higher powers always wins. It's guaranteed that for any kind of sport all of these powers are distinct.
Output
For each of the n tournaments output the number of contenders who can win.
Examples
input
3 2
1 5
5 1
10 10
output
1
2
1
input
3 2
2 2
3 3
1 10
output
1
1
3
input
3 2
2 3
1 1
3 2
output
1
1
2
Note
In the first sample:
In the first tournament there is only one sportsman, and he is the winner.
In the second tournament, there are two sportsmen, and everyone can defeat another, depending on kind of sports.
In the third tournament, the third sportsman in the strongest in both kinds of sports, so he is the winner regardless of the scheme.
题意
现在有n个人参加比赛,每个人都有k项能力值,每个能力值表示这个人在这个技能上面的能力。
现在这些人会两两进行比赛,他们会挑选一个技能进行比较,分值高的获胜,胜利者留下来,失败者离开。
你需要回答,最后究竟会有多少个人可能成为冠军。
题解
假设现在有一群人都可能获得冠军,那么必须满足任何一个人,都能找到一个人的某项技能小于等于他,也能找到一个人的某项技能强于他。
那么对于这个集合,对于每个人都能存在一个比赛方案,使得他成为冠军。
然后我们动态维护这个集群就好了,用set去维护。
你可以用图论的方式去理解。如果A能够打败B,那么连一条A->B的边,显然胜利者的含义就是如果A能够达到其他的所有点,那么A就是胜利者。
最后的胜利者集合,里面的任何两个点都能互相到达,如果已经成为了团,我们就进行缩点就好了,我们用set去缩点。
然后维护每一个团就行。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int n,k;
struct node{
int mx[10],mi[10],sz;
bool operator < (const node &b)const{
for(int i=0;i<k;i++){
if(mx[i]>b.mi[i])return false;
}
return true;
}
};
set<node>S;
int main(){
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++){
node a;
for(int j=0;j<k;j++){
scanf("%d",&a.mx[j]);
a.mi[j]=a.mx[j];a.sz=1;
}
set<node>::iterator x = S.lower_bound(a);
set<node>::iterator y = S.upper_bound(a);
while(x!=y){
a.sz+=x->sz;
for(int j=0;j<k;j++){
a.mi[j]=min(a.mi[j],x->mi[j]);
a.mx[j]=max(a.mx[j],x->mx[j]);
}
S.erase(x++);
}
S.insert(a);
cout<<S.rbegin()->sz<<endl;
}
}