COCI2014/2015CONTEST #3 honi&stogovi(LCA)
来源:互联网 发布:各行业数据查询 编辑:程序博客网 时间:2024/05/18 01:22
第四题HONI:
给出n位选手,以及每位选手两场比赛的得分。如果一位选手的两场比赛都严格大于另一位选手的两场比赛的得分,那么他第三场比赛成绩也严格大于那位选手的得分。如果两位选手的比赛总分相等,排名不分先后。求n位选手可能的排名。
模拟赛的时候实在想得太多太多了,居然用了拓扑排序- -,然后暴搜方案数;最后想到了严格大于,结果没有想到区间求和,实在遗憾啊!
正解是统计二维区间前缀和。最先用树状数组写了一遍,结果超时,后来再看看数据范围,每一场比赛的分数不超过650,于是直接统计前缀和。如果对于选手i,第一场分数记为a[i],第二场分数记为b[i],分数比他严格小的人有x人,分数比他严格大的有y人,那么他最坏的排名不会超过n-x,最好的排名不会优于y+1,于是他的排名区间就是[y+1,n-x],所以对于每一个人,我们在标记表格k[a[i]][b[i]]的值加1,代表这个分数的人数,然后统计k数组的前缀和,得到的sum[p][q]就是第一场分数小于等于p,第二场分数小于等于q的总人数。
写到这里之后,我还是WA了,
因为,特别要注意一点的是,如果第i位选手,他的第一场分数a[i]=650(最高分),那么他的排名可能与其他第一场比赛为0分,第二场比赛为b[i]分的人并列:做最坏的打算,第i位选手第三场比赛为0分,另外的选手第三场比赛650分。我们在统计严格小于的排名的时候是考虑不到这样的情况的!
比如:有两位选手,第一位选手分数为650 1 第二位选手分数为0 1,那么第一位选手的排名就是[1,1],第二位选手的排名就是[1,2]。(理解出现障碍了,对吧!)
#include<cstdio>#define MAXN 650using namespace std;int n,a[500010][2];int k[MAXN+5][MAXN+5];int sum[MAXN+5][MAXN+5];int main(){ scanf("%d",&n); for(int i = 1; i <= n; i++) { scanf("%d%d",&a[i][0],&a[i][1]);k[a[i][0]][a[i][1]]++; }for(int i = 0; i <= MAXN; i++){for(int j = 0; j <= MAXN; j++){sum[i][j] = k[i][j];if(i > 0) sum[i][j] += sum[i-1][j];if(j > 0) sum[i][j] += sum[i][j-1];if(i > 0&&j > 0) sum[i][j] -= sum[i-1][j-1];}} for(int i = 1; i <= n; i++) { int t1,t2;t1 = sum[a[i][0]-1][a[i][1]-1] + k[a[i][0]][0]*(a[i][1] == MAXN) + k[0][a[i][1]]*(a[i][0] == MAXN);//严格小于,当有一场的分数为650的最高分时//另外一场分数为b[i]另一场为0分的人永远也不可能超过他t2 = sum[650][650] - sum[650][a[i][1]] - sum[a[i][0]][650] + sum[a[i][0]][a[i][1]];//严格大于printf("%d %d\n",t2+1,n-t1); }}
第五题STOGOVI:
模拟赛的时候抽风,直接写了vector来模拟,然后各种爆内存超时。
其实仔细看一下就会发现,这就是一道在线的LCA的题目。对于a操作,就是新增一个节点i,他是v的儿子节点;对于操作b,就是求节点v属于哪个节点的集合,然后把节点i放入节点v的父亲节点集合;然后操作c就是把节点i放入节点v的集合,然后求v,w最近公共祖先的深度。
#include<cstdio>#include<iostream>#include<cstring>#define MAXN 300010using namespace std;int belong[MAXN];//相当于是一个并查集int p[MAXN][20];int dep[MAXN];int n,v,w;char ops[3];int lca(int a,int b){ int i,j; if(dep[a] < dep[b]) swap(a,b); for(i = 0; (1<<i) <= dep[a]; i++); i--; for(j = i; j >= 0; j--) if(dep[a] - (1<<j) >= dep[b]) a = p[a][j]; if(a == b) return a; for(j = i; j >= 0; j--) if(p[a][j] != -1&&p[a][j] != p[b][j]) { a = p[a][j]; b = p[b][j]; } return p[a][0];}int main(){ memset(p,-1,sizeof p); scanf("%d",&n); for(int i = 1; i <= n; i++) { scanf("%s%d",ops,&v); v = belong[v]; if(ops[0] == 'a')//增加新的节点 { belong[i] = i; dep[i] = dep[v] + 1; p[i][0] = v; for(int j = 1; j <= 20; j++)//宁可多循环几次,最先按照模板写成了(1<<j)<=20 if(p[i][j-1] != -1) p[i][j] = p[p[i][j-1]][j-1]; } else if(ops[0] == 'b')//复制并删除,即该栈并入他的父亲的集合 { printf("%d\n",v); belong[i] = p[v][0]; } else //找出两点的最近公共祖先,并求深度 { scanf("%d",&w); w = belong[w]; belong[i] = v; printf("%d\n",dep[lca(v,w)]); } }}
- COCI2014/2015CONTEST #3 honi&stogovi(LCA)
- COCI2014 stogovi
- COCI2014/2015CONTEST #3 dom
- COCI2014/2015CONTEST #3 kamioni
- COCI CONTEST #3 29.11.2014 STOGOVI
- COCI CONTEST #3 29.11.2014 T5 STOGOVI
- 模拟赛心得体会&COCI2014/2015CONTEST #3 silueta&strojopis
- COCI CONTEST #3 29.11.2014 HONI
- COCI CONTEST #3 29.11.2014 T4 HONI
- zjnu1726 STOGOVI (lca)
- 模拟赛心得体会&COCI2014/2015CONTEST #1
- COCI2014/2015 Contest#2 F Solution
- 2017.5.17 COCI2014/2015 Contest#5
- coci2014 contest#1 T5-zabavz—— dp
- coci2014 contest#1 T3-PIRAMIDA—— 数学
- 【jzoj3919】【COCI2014/2015 Round1 KAMP】【志愿者】【树形动态规划】
- hdu 5296 - Annoying problem(2015 Multi-University Training Contest 1 )LCA
- HDU 6065 RXD, tree and sequence (LCA, 2017 Multi-Univ Training Contest 3)
- IT人—SHH开山之作
- hadoop中启动namenode等出现的一些问题
- 第2周项目0 宣告“主权”
- 非负矩阵分解NMF
- 第一个任务
- COCI2014/2015CONTEST #3 honi&stogovi(LCA)
- Python学习写一小程序,从某一目录下所以文件中查询某字段,并显示文件名和所在行
- IOS后台定位
- 免费SVN地址
- 第一周项目 C/C++语言中函数参数传递的三种方式
- 2015腾讯校园招聘软件测试部分笔试题
- matlab函数——shading函数
- 密码123456,这意味着什么?
- Hadoop基本命令