1 条题解

  • 0
    @ 2025-8-24 21:53:48

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Thunder_S
    咖啡馆与广场有三个街区,就像霓虹灯到月亮的距离。

    搬运于2025-08-24 21:53:48,当前版本为作者最后更新于2022-02-14 20:15:31,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    Solution

    题目很长,简单来说就是维护一个比赛系统。

    先给出要维护的东西:

    每场比赛每个用户对应的 AC 数量,每场比赛对应 AC 数量的人数,每个提交对应的编号、用户、比赛、和结果。

    下面分操作讲述。


    新建比赛。

    其实新建比赛是没有用的,因为之后其他的操作中都会给出对应的比赛编号和题目编号(或者提交编号),所以并不需要记录比赛中有哪些题目。


    提交。

    对于一个 UNAC 的提交,记录每场比赛有哪些人是交过题了,如果当前这个提交对应的用户之前交过题,那么这个提交是不用管的,否则需要将 AC 数量为 0 的人数 +1(在对应的比赛中)。

    如果是 AC 的提交,则将对应用户在对应比赛中的 AC 数量 +1。注意我们要先判断这个人是否曾经 AC 过这道题目,但如果直接开数组会爆空间,所以要用链式前向星,将对于这个用户和这道题对应比赛的 AC 数量打在连向对应比赛的边上(这里可能有点难懂,可以结合下面的代码理解)。


    查询排名。

    相当于给出一个过题数,在对应比赛中查找有多少人的过题数大于,多少人过题数等于。这里可以用数据结构或者前缀/后缀和。


    重测。

    跟提交差不多,如果原本的状态是 UNAC 的话,不需要管。

    如果是 AC,则只需要将对应用户的 AC 数量 -1。

    Code

    #include<cstdio>
    #define N 5005
    #define M 350005
    using namespace std;
    struct sub
    {
        int pid,cid,uid;
        bool res;
    }sub[M];
    struct contest
    {
        int num[N],solve[N];
    }con[55];
    struct node
    {
        int to,next;
    }a[M];
    int n,m,q,id,sid,cid,pid,uid,tot,cnt[M],head[N][N];
    bool b[55][N];
    char ch[20];
    int read()
    {
        int res=0;char ch=getchar();
        while (ch<'0'||ch>'9') ch=getchar();
        while (ch>='0'&&ch<='9') res=(res<<1)+(res<<3)+(ch-'0'),ch=getchar();
        return res;
    }
    void add(int uid,int pid,int cid)
    {
        a[++tot].to=cid;
        a[tot].next=head[uid][pid];
        head[uid][pid]=tot;
    }
    int find(int uid,int pid,int cid)
    {
        for (int i=head[uid][pid];i;i=a[i].next)
        {
            int v=a[i].to;
            if (v==cid) return i;
        }
        return 0;
    }
    int main()
    {
        n=read();m=read();q=read();
        while (q--)
        {
            scanf("%s",ch);
            if (ch[0]=='c')
            {
                int num,x;
                cid=read();num=read();
                for (int i=1;i<=num;++i)
                    x=read();
            }
            else if (ch[0]=='s')
            {
                int sid,cid,pid,uid;
                sid=read();cid=read();pid=read();uid=read();scanf("%s",ch);
                sub[sid].cid=cid;sub[sid].pid=pid;sub[sid].uid=uid;sub[sid].res=(ch[0]=='A');
                if (!b[cid][uid])
                {
                    b[cid][uid]=true;
                    con[cid].num[0]++;
                }
                if (ch[0]=='A')
                {
                    id=find(uid,pid,cid);
                    if (!id) add(uid,pid,cid),id=tot;
                    ++cnt[id];
                    if (cnt[id]==1) con[cid].num[++con[cid].solve[uid]]++;
                }
            }
            else if (ch[0]=='g')
            {
                cid=read();uid=read();
                int pnum=con[cid].solve[uid];
                printf("%d %d %d %d\n",uid,pnum,con[cid].num[pnum+1]+1,con[cid].num[pnum]);
            }
            else if (ch[0]=='r')
            {
                sid=read();
                uid=sub[sid].uid;cid=sub[sid].cid;pid=sub[sid].pid;
                if (sub[sid].res)
                {
                    int id=find(uid,pid,cid);
                    --cnt[id];
                    if (cnt[id]==0) con[cid].num[con[cid].solve[uid]--]--;
                }
            }
        }
        return 0;
    }
    
    • 1

    信息

    ID
    2849
    时间
    1000ms
    内存
    128MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者