HDU 5096 题解

来源:互联网 发布:网络贷款利息计算器 编辑:程序博客网 时间:2024/06/01 13:08

题目大意

实现一个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;}
0 0
原创粉丝点击