Gym

题目传送门

题目大意:

n个人,m次提交,每次提交都代表某支队伍做出一题,并且给出罚时,让你输出每次提交后,编号为1的队伍的排名。

思路:

      首先处理ac和罚时,由于罚时最大1000,最多有1e5次,要保证ac比罚时重要的多,所以一次ac,权值加1e8 再减 罚时。

      维护一个小根堆,由于元素没有重复的,所以可以直接用set。

      更新的如果是team1,把更新后的team1的权值和小根堆堆顶比较,小于等于team1的删除。

      更新的如果是其他队伍,先判断是否在堆内,如果在,就先删去堆中原有的状态,再把更新后的塞回堆,如果不在堆内,就判断一下有没有比team1大,如果大于,则塞入堆内。

     每次只要输出堆的大小加一就可以了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string.h>
#include<sstream>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#define CLR(a,b) memset((a),(b),sizeof((a))) 
using namespace std;
typedef long long ll;
inline int rd() {
    int f = 1; int x = 0; char s = getchar();
    while (s<'0' || s>'9') { if (s == '-')f = -1; s = getchar(); }
    while (s >= '0'&&s <= '9') { x = x * 10 + s - '0'; s = getchar(); }x *= f;
    return x;
}
const int maxn = 100010;
struct dian {
    ll val;
    int id;
    friend bool operator<(const dian &a, const dian &b) {
        if (a.val - b.val)return a.val < b.val;
        return a.id < b.id;
    }
}a[maxn];
set <dian > s;
struct node {
    int team; ll time;
}op[maxn];
int n, m;
int vis[maxn];
ll acp = 1e8 + 1, time , val;
int team;
int main() {
    cin >> n >> m;
    val = 0;
    for (int i = 1; i <= n; i++) {
        a[i].id = i;
    }
    for (int i = 1; i <= m; i++) {
        scanf("%d%lld", &team, &time);
        if (team != 1) {
            if (vis[team]) {
                s.erase(a[team]);
                a[team].val += acp - time;
                s.insert(a[team]);
                printf("%d
", 1 + (int)s.size());
            }
            else {
                a[team].val += acp - time;
                if (a[team].val > val) {
                    s.insert(a[team]);
                    vis[team] = 1;
                //    printf("i:%d
",i);
                //    printf("size:%d
", s.size());
                }
                
                printf("%d
", 1 + (int)s.size());
            }
        }
        else {
            val += acp - time;
            set<dian >::iterator it;
            if (s.empty()) {
                printf("1
");
                continue;
            }
            it = s.begin();
            while (it->val <= val) {
                s.erase(it);
                vis[it->id] = 0;
                if (s.empty())break;
                it = s.begin();
            }
            printf("%d
", 1 + (int)s.size());
        }
    }

}
原文地址:https://www.cnblogs.com/mountaink/p/9564012.html