1 条题解
-
0
自动搬运
来自洛谷,原作者为

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
- 上传者