Description
现
在
有
n
个
队
伍
,
每
个
队
伍
的
有
两
个
值
(
a
,
b
)
:
分
别
表
示
通
过
的
题
目
和
罚
时
。
现在有n个队伍,每个队伍的有两个值(a,b):分别表示通过的题目和罚时。
现在有n个队伍,每个队伍的有两个值(a,b):分别表示通过的题目和罚时。
题
目
越
多
,
排
名
越
靠
前
,
如
果
题
目
数
相
同
则
b
罚
时
越
少
的
队
伍
越
靠
前
。
题目越多,排名越靠前,如果题目数相同则b罚时越少的队伍越靠前。
题目越多,排名越靠前,如果题目数相同则b罚时越少的队伍越靠前。
现
在
初
始
化
每
个
人
的
值
都
为
(
0
,
0
)
。
现在初始化每个人的值都为(0,0)。
现在初始化每个人的值都为(0,0)。
现
在
有
m
次
提
交
,
每
次
操
作
被
定
义
为
(
t
,
p
)
表
示
第
t
支
队
伍
做
出
了
一
道
题
,
且
罚
时
为
p
现在有m次提交,每次操作被定义为(t,p)表示第t支队伍做出了一道题,且罚时为p
现在有m次提交,每次操作被定义为(t,p)表示第t支队伍做出了一道题,且罚时为p
要
求
求
出
每
一
提
交
后
第
1
支
队
伍
的
排
名
。
要求求出每一提交后第1支队伍的排名。
要求求出每一提交后第1支队伍的排名。
Input
1
≤
n
,
m
≤
1
0
5
1\leq n,m\leq 10^{5}
1≤n,m≤105
1
≤
t
≤
n
1\leq t \leq n
1≤t≤n
1
≤
p
≤
1000
1 \leq p \leq 1000
1≤p≤1000
Output
输 出 m 行 , 每 行 表 示 提 交 后 队 伍 1 的 排 名 。 输出m行,每行表示提交后队伍1的排名。 输出m行,每行表示提交后队伍1的排名。
Solution
S
o
l
u
t
i
o
n
1
\color {red}{Solution 1}
Solution1 优先队列模拟
优先级定义为常识。
优
先
队
列
里
存
放
的
都
是
大
于
1
号
队
伍
的
队
伍
优先队列里存放的都是大于1号队伍的队伍
优先队列里存放的都是大于1号队伍的队伍
考虑用两个数组纪录下每次提交后所有队伍的状态。
修
改
的
队
伍
为
t
,
罚
时
为
p
。
修改的队伍为t,罚时为p。
修改的队伍为t,罚时为p。
如
果
修
改
的
不
是
1
号
队
伍
(
t
≠
1
)
,
更
新
对
应
数
组
。
如果修改的不是1号队伍(t \neq 1),更新对应数组。
如果修改的不是1号队伍(t̸=1),更新对应数组。
更
新
后
如
果
大
于
1
号
队
伍
且
不
在
优
先
队
列
中
,
则
t
是
因
为
这
次
提
交
超
过
了
1
号
,
于
是
加
入
队
列
。
更新后如果大于1号队伍且不在优先队列中,则t是因为这次提交超过了1号,于是加入队列。
更新后如果大于1号队伍且不在优先队列中,则t是因为这次提交超过了1号,于是加入队列。
如
果
是
1
号
队
伍
。
更
新
1
号
队
伍
的
信
息
,
然
后
不
断
从
优
先
队
列
弹
出
最
小
的
队
伍
,
如
果
小
于
1
号
就
弹
出
。
如果是1号队伍。更新1号队伍的信息,然后不断从优先队列弹出最小的队伍,如果小于1号就弹出。
如果是1号队伍。更新1号队伍的信息,然后不断从优先队列弹出最小的队伍,如果小于1号就弹出。
需
要
注
意
的
是
弹
出
的
队
伍
信
息
可
能
是
之
前
的
,
弹
出
后
需
要
更
新
后
重
新
判
断
是
否
大
于
1
号
并
加
入
队
列
。
需要注意的是弹出的队伍信息可能是之前的,弹出后需要更新后重新判断是否大于1号并加入队列。
需要注意的是弹出的队伍信息可能是之前的,弹出后需要更新后重新判断是否大于1号并加入队列。
S
o
l
u
t
i
o
n
2
\color {red}{Solution 2}
Solution2 离散化+数状数组
离散化
预先处理出每次提交后所有的状态。
排序后获得每个状态的离散后的对应位置。
然后依次更新查询即可。
Codes
c o d e 1 \color {red}{code 1} code1 优先队列模拟
#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} code2 离散化树状数组
#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;
}