Codeforces Round #443 (Div. 1) C. Tournament 思维题

C. Tournament
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
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
题意:每个人有k个属性,如果他其中有一个属性大于他的对手,那么他就有可能打败他的对手,每次比赛失败的人退场,问给出任意的出场顺序,问有多少个人有希望获得胜利,每一年会来一个新的选手,对于每一年输出这一年可能获胜的人。
做法:如果两个人你可以打败我,我也可以打败你,就可以把这两个人看做是一个集合,只要有人能打败这个集合的人,又会被这个集合的人打败,那么就把他们看成一个集合,每次输出最大集合的大小就好了。

#include
#include
#include
#include
using namespace std;
const int N = 5e4+100;
int n,k;
struct node{
    int sz;
    int mn[15],mx[15];
    void init(int a){
        sz = 0;
        for(int i= 1;i <= k;i++){
            mx[i] = mn[i] = a;
        }
    }
    void unit(node a){
        sz += a.sz;
        for(int i = 1;i <= k;i ++){
            mn[i] = min(mn[i],a.mn[i]);
            mx[i] = max(mx[i],a.mx[i]);
        }
    }
    bool operator<(const node&p)const{
        for(int i = 1;i <= k;i ++){
            if(mx[i] > p.mn[i]) return false;
        }
        return true;
    }
};
set s;
vector<set::iterator>del;
int main(){
    scanf("%d %d",&n,&k);
    node now;
    for(int i = 1;i <= n;i ++){
        for(int j = 1;j <= k;j ++)
        scanf("%d",&now.mn[j]),now.mx[j] = now.mn[j];
        now.sz = 1;
        set::iterator l,r,iter;
        //l = lower_bound(s.begin(),s.end(),now);
        //r = upper_bound(s.begin(),s.end(),now);
        r = s.upper_bound(now);
        l = s.lower_bound(now);
        for(iter = l;iter != r;iter ++){
            now.unit(*iter);
            del.push_back(iter);
        }
        for(int j = 0;j< del.size();j ++){
            s.erase(del[j]);
        }
        del.clear();
        s.insert(now);
        iter = s.end();
        iter --;
        printf("%d\n",iter->sz);
    }
    return 0;
}

你可能感兴趣的:(算法理解)