Educational Codeforces Round 87 (Rated for Div. 2) 参与排名人数11499,比赛前遇到2次延时,17:05-17:15,17:15-17:20
[codeforces 1354D] Multiset 线段树(由数值找节点位置,由排名找节点位置)
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1354/problem/D
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
D - Multiset | GNU C++17 | Accepted | 702 ms | 15600 KB |
思路:线段树(由数值找节点位置,由排名找节点位置)
样例数据生成过程,如下所示
Input:
6 2
1 1 1 2 3 4
5 6
Output:
6
AC代码如下
#include <stdio.h>
#define maxn 1000010
#define lson k<<1
#define rson k<<1|1
int tree[maxn<<2];//tree[]统计区间内,数的数量
void insert(int k,int l,int r,int x){//此处x表示数值
if(l==r){
tree[k]++;
return;
}
int mid=(l+r)>>1;//mid分裂数值区间
if(x<=mid)insert(lson,l,mid,x);
else insert(rson,mid+1,r,x);
tree[k]=tree[lson]+tree[rson];
}
int del(int k,int l,int r,int x){//此处x表示排名
if(l==r){
tree[k]--;
return l;
}
int mid=(l+r)>>1,p;//mid分裂数量区间
if(x<=tree[lson])p=del(lson,l,mid,x);
else p=del(rson,mid+1,r,x-tree[lson]);
tree[k]=tree[lson]+tree[rson];
return p;
}
int main(){
int n,q,i,x;
scanf("%d%d",&n,&q);
for(i=1;i<=n;i++)scanf("%d",&x),insert(1,1,n,x);
while(q--){
scanf("%d",&x);
if(x>0)insert(1,1,n,x);
else del(1,1,n,-x);
}
printf("%d\n",tree[1]?del(1,1,n,1):0);
return 0;
}