题目大意
实现一个acm的排名系统。
S a:b:c:d
b队在a分钟提交了c题,状态为d
如果b对在5分钟内有其他有效提交,则这次提交为无效提交。如果没有AC,这道题的罚时+20分钟。通过一题后才累加这道题的罚时。
R a
查询a队的排名
Q a
查询排名为a的队伍编号
排名方式:
以AC题数为第一关键字,罚时为第二关键字,最后AC时间为第三关键字。
对于没有A题的队伍,编号小的队靠前。
我的做法
替罪羊树
AC一题罚时就-10000000
其他的直接搞。
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;
int lsa[10010];
int lst[10010];
int ac[10010][11];
int fti[100010][11];
int ti[10010];
struct cmp
{
bool operator ()(int a,int b)
{
return lsa[a]<lsa[b];
}
};
struct tree
{
int sum;
int size;
int v;
tree *ls,*rs;
set<int,cmp> t;
tree()
{
sum=0;
size=0;
v=0;
ls=rs=0;
}
};
tree *top;
tree **needbuild;
tree a[10010];
int cnt;
void mt(tree *&p)
{
p->sum=p->t.size();
p->size=1;
if(p->ls)
{
p->sum+=p->ls->sum;
p->size+=p->ls->size;
}
if(p->rs)
{
p->sum+=p->rs->sum;
p->size+=p->rs->size;
}
}
void _insert(tree *&p,int x)
{
if(!p)
{
p=new tree;
p->sum=p->size=1;
p->v=ti[x];
p->t.clear();
p->t.insert(x);
return;
}
if(p->v==ti[x])
{
p->sum++;
p->t.insert(x);
return;
}
if(ti[x]<p->v)
_insert(p->ls,x);
else
_insert(p->rs,x);
mt(p);
if(p->ls&&p->ls->size>0.7*p->size||p->rs&&p->rs->size>0.7*p->size)
needbuild=&p;
}
void prebuild(tree *&p)
{
if(p->ls)
prebuild(p->ls);
if(p->size)
a[++cnt]=*p;
if(p->rs)
prebuild(p->rs);
delete p;
p=0;
}
void build(tree *&p,int l,int r)
{
if(l>r)
return;
int mid=(l+r)>>1;
p=new tree(a[mid]);
p->ls=p->rs=0;
build(p->ls,l,mid-1);
build(p->rs,mid+1,r);
mt(p);
}
void insert(int x)
{
needbuild=0;
_insert(top,x);
if(needbuild)
{
cnt=0;
prebuild(*needbuild);
build(*needbuild,1,cnt);
}
}
void del(tree *&p,int x)
{
if(!p)
return;
if(p->v==ti[x])
{
p->sum--;
p->t.erase(p->t.find(x));
return;
}
if(ti[x]<p->v)
del(p->ls,x);
else
del(p->rs,x);
mt(p);
}
int find(tree *&p,int x)
{
if(ti[x]>p->v)
return find(p->rs,x);
int rs=0;
if(p->rs)
rs=p->rs->sum;
if(ti[x]<p->v)
return find(p->ls,x)+p->t.size()+rs;
return rs+1;
}
int kth(tree *&p,int x)
{
if(!p||x<=0||x>p->sum)
return 0;
int rs=0;
if(p->rs)
rs=p->rs->sum;
if(x<=rs)
return kth(p->rs,x);
if(p->t.size()&&x==rs+1)
return *(p->t.begin());
return kth(p->ls,x-rs-p->t.size());
}
void remove(tree *&p)
{
if(p->ls)
remove(p->ls);
if(p->rs)
remove(p->rs);
delete p;
p=0;
}
int main()
{
int n,m;
char op[50];
while(~scanf("%d%d",&n,&m))
{
int i;
if(top)
remove(top);
fill(lst+1,lst+n+1,-5);
memset(ac,0,sizeof(ac));
memset(fti,0,sizeof(fti));
memset(ti,0,sizeof(ti));
for(i=1;i<=n;i++)
{
lsa[i]=i-n-1;
insert(i);
}
int min,id,res,no;
char c;
int now=0;
int tt=0;
int ttt=0;
while(~scanf("%s",op)&&op[0]!='C')
{
ttt++;
if(op[0]=='S')
{
scanf("%d:%d:%c:%d",&min,&no,&c,&res);
no++;
id=c-'A'+1;
if(min-lst[no]<5||ac[no][id])
continue;
lst[no]=min;
if(res==1)
{
tt++;
printf("[%d][%c]\n",no-1,c);
del(top,no);
if(top->sum*2<=top->size)
{
cnt=0;
prebuild(top);
build(top,1,cnt);
}
lsa[no]=++now;
ac[no][id]=1;
ti[no]+=10000000-fti[no][id]-min;
insert(no);
}
else
fti[no][id]+=20;
}
else if(op[0]=='R')
{
scanf("%d",&no);
no++;
printf("%d\n",find(top,no));
}
else
{
scanf("%d",&no);
printf("%d\n",kth(top,no)-1);
}
}
scanf("%s",op);
printf("\n");
}
return 0;
}