Gym - 101572G Galactic Collegiate Programming Contest 树状数组|优先队列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38013346/article/details/82257539

Description

n ( a , b ) : 现在有n个队伍,每个队伍的有两个值(a,b):分别表示通过的题目和罚时。
b 题目越多,排名越靠前,如果题目数相同则b罚时越少的队伍越靠前。
( 0 , 0 ) 现在初始化每个人的值都为(0,0)。
m ( t , p ) t p 现在有m次提交,每次操作被定义为(t,p)表示第t支队伍做出了一道题,且罚时为p
1 要求求出每一提交后第1支队伍的排名。


Input

1 n , m 1 0 5 1\leq n,m\leq 10^{5}
1 t n 1\leq t \leq n
1 p 1000 1 \leq p \leq 1000


Output

m 1 输出m行,每行表示提交后队伍1的排名。


Solution

S o l u t i o n 1 \color {red}{Solution 1} 优先队列模拟
优先级定义为常识。
1 优先队列里存放的都是大于1号队伍的队伍
考虑用两个数组纪录下每次提交后所有队伍的状态。
t , p 修改的队伍为t,罚时为p。
1 ( t 1 ) 如果修改的不是1号队伍(t \neq 1),更新对应数组。
1 t 1 更新后如果大于1号队伍且不在优先队列中,则t是因为这次提交超过了1号,于是加入队列。
1 1 1 如果是1号队伍。更新1号队伍的信息,然后不断从优先队列弹出最小的队伍,如果小于1号就弹出。
1 需要注意的是弹出的队伍信息可能是之前的,弹出后需要更新后重新判断是否大于1号并加入队列。

S o l u t i o n 2 \color {red}{Solution 2} 离散化+数状数组
离散化
预先处理出每次提交后所有的状态。
排序后获得每个状态的离散后的对应位置。
然后依次更新查询即可。


Codes

c o d e 1 \color {red}{code 1} 优先队列模拟

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
struct Node {
    int id,pro,pen;
    Node(){}
    Node(int _id,int _p,int _e) {id = id;pro = _p;pen = _e;}
    bool operator < (const Node& a) const{
        return (pro < a.pro || (pro == a.pro && pen > a.pen));
    }
    bool operator > (const Node& a) const{
        return (pro > a.pro || (pro == a.pro && pen < a.pen));
    }
};
Node arr[maxn];
bool vis[maxn];
int n,m,t,p;
priority_queue<Node,vector<Node>,greater<Node> > qu;
void cal() {
    while(!qu.empty()) {
        Node tmp = qu.top();
        if(arr[1] < tmp) break;
        qu.pop();
        tmp = arr[tmp.id];
        if(arr[1] < tmp) qu.push(tmp);
        else vis[tmp.id] = false;
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m)) {
        while(!qu.empty()) qu.pop();
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++) arr[i].id = i,arr[i].pro = arr[i].pen = 0;
        for(int i=0;i<m;i++) {
            scanf("%d%d",&t,&p);
            if(t == 1){
                arr[1].pro++;
                arr[1].pen+=p;
                cal();
            }
            else {
                arr[t].pro++;
                arr[t].pen+=p;
                if(arr[1] < arr[t] && !vis[t]) {
                    vis[t] = true;
                    qu.push(arr[t]);
                }
            }
            printf("%d\n",(int)qu.size()+1);
        }
    }
    return 0;
}

c o d e 2 \color {red}{code 2} 离散化树状数组

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
struct Node {
    int pro,pen;
    Node(){}
    Node(int _p,int _pe){pro = _p;pen = _pe;}
    bool operator == (const Node &a) const {
        return pro == a.pro && pen == a.pen;
    }
    bool operator < (const Node &a) const {
        return (pro < a.pro || (pro == a.pro && pen > a.pen));
    }
    bool operator > (const Node &a) const {
        return (pro > a.pro || (pro == a.pro && pen < a.pen));
    }
};
struct BIT {
    int c[maxn];
    int lowbit(int x) {return x & -x;}
    void init() {
        memset(c,0,sizeof(c));
    }
    void update(int pos,int val) {
        for(int i=pos;i<maxn;i+=lowbit(i)) c[i] += val;
    }
    int sum(int pos) {
        int ans = 0;
        for(int i=pos;i;i-=lowbit(i)) ans += c[i];
        return ans;
    }
}bit;
vector<Node> way;
Node pre,tmp,one;
int n,m,arr[maxn],brr[maxn],qu[maxn],fa[maxn];
int getid(const Node &a) {
    return lower_bound(way.begin(),way.end(),a) - way.begin() + 1;
}
int main()
{
    while(~scanf("%d%d",&n,&m)) {
        memset(arr,0,sizeof(arr));
        memset(brr,0,sizeof(brr));
        way.push_back(Node(0,0));
        for(int i=1,u,v;i<=m;i++) {
            scanf("%d%d",&qu[i],&fa[i]);
            arr[qu[i]]++;brr[qu[i]]+=fa[i];
            way.push_back(Node(arr[qu[i]],brr[qu[i]]));
        }
        sort(way.begin(),way.end());
        
        memset(arr,0,sizeof(arr));
        memset(brr,0,sizeof(brr));
        bit.init();
        bit.update(1,n);
        for(int i=1,pos,now,it;i<=m;i++) {
            pre = Node(arr[qu[i]],brr[qu[i]]);
            arr[qu[i]]++;brr[qu[i]]+=fa[i];
            tmp = Node(arr[qu[i]],brr[qu[i]]);
            one = Node(arr[1],brr[1]);
            pos = getid(pre),now = getid(tmp),it = getid(one);
            bit.update(pos,-1);
            bit.update(now,1);
            int res = n - bit.sum(it);
            printf("%d\n",res+1);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_38013346/article/details/82257539