9.22am的题解

今天上午考数据结构,下午综合,都不太难,随附题解一篇。


AM

T1 校门外的树

时间限制: 1 Sec 内存限制: 128 MB

题目描述

校门外有很多树,学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两种操作:
1)K=1,读入 l,r 表示在 l 到 r 之间种上一种树,每次操作种的树的种类都不同;
2)K=2,读入 l,r 表示询问 l 到 r 之间有多少种树。
注意:每个位置都可以重复种树。

输入

第一行 n,m 表示道路总长为 n,共有 m 个操作;
接下来 m 行为 m 个操作。

输出

对于每个 k=2 输出一个答案。

样例输入
5 4
1 1 3
2 2 5
1 2 4
2 3 5
样例输出
1
2
提示

【数据范围与提示】

对于 20% 的数据,1≤n,m≤100;

对于 60% 的数据,1≤n≤103 ,1≤m≤5×10 4 ;

对于 100% 的数据,1≤n,m≤5×10 4 ,保证 l,r>0。

本题与HH的项链颇有几分相似,如有需要者 https://www.luogu.com.cn/problem/P1972;

本题O(n^2)是过不去的,我们思考O(nlogn)的做法;

由于询问的是区间中树的种类数,所以问询区间中相同种类的树只有一个会起作用;

询问的右端点有多少个树的左端点,就代表了有可能有多少个树区间处于询问区间内;

而询问的左端点有多少个树的右端点,就代表了上述有多少个树区间实际并不处于询问区间内;(这一点应该好想);

于是答案即为ask(右端点的左括号个数)-ask(左端点的右括号个数);

我们发现修改和查询都可以在树状数组中执行,于是整个算法效率为O(mlogn)。

#include<bits/stdc++.h>
using namespace std;int op,n,m,a,b;int c1[50005],c2[50005];void change(int x,bool flag)
{while(x<=n){if(!flag)c1[x]++;else c2[x]++;x+=x&(-x);}
}int ask(int x,bool flag)
{int ret=0;while(x){if(!flag)ret+=c1[x];else ret+=c2[x]x-=x&(-x);}return ret;
}int main()
{scanf("%d%d",&n,&m);for(int i=1; i<=m; i++){scanf("%d%d%d",&op,&a,&b);if(op==1){change(a,op-1);change(b,op);}else{printf("%d\n",ask(b,op-1)-ask(a-1,op));}}
}

T2 堆蛋糕

时间限制: 3 Sec 内存限制: 128 MB

其实小布是一个十分犀利的蛋糕师。他最喜欢的食物就是蛋糕。

一天,他自己做出了N个圆柱状的蛋糕,每个蛋糕都有一个底面圆的半径Ri。高度都是一样的。

小布在开始享用他的蛋糕大餐之前忽然觉得,圆柱状的蛋糕没有什么诱惑力。小布看到了别人结婚用的蛋糕都是很多很多层的,那样的蛋糕才比较给力。但是堆太多层的蛋糕比较困难,于是小布想要堆出许多三层的蛋糕,再开始自己的蛋糕大餐。

当然,作为蛋糕师,小布在堆蛋糕的时候不会对蛋糕的形状有任何破坏,而且,小布希望三层蛋糕的半径从上往下严格递增。这才是一个普通的好蛋糕。

但是小布在考虑一个十分重要的问题,最多可以堆出多少三层蛋糕呢?

输入

输入第一行仅包含一个整数N,表示蛋糕的数量。

接下来N个整数,表示每个蛋糕半径的大小Ri。

N<=3,000,000 Ri<=N

输出

输出一行仅包含一个整数,表示最多可以做成多少个蛋糕

样例输入
6
1 2 3 4 3 2
样例输出
2

本题贪心,需用优先队列优化。

策略:每次选择三个出现次数最大的半径,并都减去它们中的最小值,把不为0的入队,直到优先队列size小于3。

#include<bits/stdc++.h>
using namespace std;int n,a[3000005],x,ans,minn;int y[4];priority_queue < int > q;int main()
{scanf("%d",&n);for(int i=1; i<=n; i++){scanf("%d",&x);a[x]++;//观察到r较小,可用类似桶排的想法保存信息}for(int i=1; i<=3000000; i++){if(a[i])q.push(a[i]);//为啊a[i]=0的被筛掉}while(q.size()>=3){y[1]=q.top(),q.pop();y[2]=q.top(),q.pop();y[3]=q.top(),q.pop();minn=min(y[1],min(y[2],y[3]));ans+=minn;for(int i=1; i<=3; i++){if(y[i]-minn==0){continue;  }else q.push(y[i]-minn);}}printf("%d",ans);
}

T3 清点人数

时间限制: 1 Sec 内存限制: 128 MB

题目描述

NK 中学组织同学们去五云山寨参加社会实践活动,按惯例要乘坐火车去。由于 NK 中学的学生很多,在火车开之前必须清点好人数。
初始时,火车上没有学生。当同学们开始上火车时,年级主任从第一节车厢出发走到最后一节车厢,每节车厢随时都有可能有同学上下。年级主任走到第 mm 节车厢时,他想知道前 mm 节车厢上一共有多少学生,但是他没有调头往回走的习惯。也就是说每次当他提问时,mm 总会比前一次大。

输入

第一行两个整数 n,k,表示火车共有 n 节车厢以及 k 个事件。
接下来有 k 行,按时间先后给出 k 个事件,每行开头都有一个字母 A,B 或 C。
如果字母为 A,接下来是一个数 m,表示年级主任现在在第 m 节车厢;
如果字母为 B,接下来是两个数 m,p,表示在第 m 节车厢有 p 名学生上车;
如果字母为 C,接下来是两个数 m,p,表示在第 m 节车厢有 p 名学生下车。
学生总人数不会超过 105 。

输出

对于每个 A ,输出一行,一个整数,表示年级主任的问题的答案。

样例输入

10 7
A 1
B 1 1
B 3 1
B 4 1
A 2
A 3
A 10

样例输出

0
1
2
3

提示

【数据范围与提示】

对于 30% 的数据,1≤n,k≤104 ,至少有 3000 个 A;

对于 100% 的数据,1≤n≤5×105 ,1≤k≤105 ,至少有 3×104 个 A。

本题A少,有可能n^2可过,有人过了,但笔者没有试过,故不加定论。

树状数组是可过的。

可以把本题看做树状数组的板。

#include<bits/stdc++.h>
using namespace std;int n,k,m,p,mm,c[500005];char op;int ask(int x)
{int ret=0;while(x){ret+=c[x];x-=x&(-x);}return ret;
}void change(int x,int num)
{while(x<=n){c[x]+=num;x+=x&(-x);}
}int main()
{scanf("%d%d",&n,&k);for(int i=1;i<=k;i++){scanf("%s",&op);if(op=='A'){scanf("%d",&mm);printf("%d\n",ask(mm));}else if(op=='B'){scanf("%d%d",&m,&p);change(m,p);}else{scanf("%d%d",&m,&p);change(m,-p);}}
}
/*
10 8
A 1
B 3 1
B 1 4
B 4 1
A 2
A 3
C 1 1
A 10*/

T4 打鼹(yan)鼠

时间限制: 1 Sec 内存限制: 128 MB

题目描述

在这个“打鼹鼠”的游戏中,鼹鼠会不时地从洞中钻出来,不过不会从洞口钻进去(鼹鼠真胆大……)。洞口都在一个大小为n(n<=1024)的正方形中。这个正方形在一个平面直角坐标系中,左下角为(0,0),右上角为(n-1,n-1)。洞口所在的位置都是整点,就是横纵坐标都为整数的点。而SuperBrother也不时地会想知道某一个范围的鼹鼠总数。这就是你的任务。

输入

输入有多行。
第一行,一个数n,表示鼹鼠的范围。
以后每一行开头都有一个数m,表示不同的操作:
m=1,那么后面跟着3个数x,y,k(0<=x,y<n),表示在点(x,y)处新出现了k只鼹鼠;
m=2,那么后面跟着4个数x1,y1,x2,y2(0<=x1<=x2<n,0<=y1<=y2<n),表示询问矩形(x1,y1)-(x2,y2)内的鼹鼠数量;
m=3,表示老师来了,不能玩了。保证这个数会在输入的最后一行。
询问数不会超过10000,鼹鼠数不会超过maxlongint。

输出

对于每个m=2,输出一行数,这行数只有一个数,即所询问的区域内鼹鼠的个数。

样例输入

4
1 2 2 5
2 0 0 2 3
3

样例输出

5

分析

先打三遍鼹鼹鼹,这是过题的关键(划掉

横看像什么二维树状数组,我旁边的老哥已经开始自创算法了…

其实不难。

我们把要求在线问题离线解决,倒序处理。M^2可解。

#include<bits/stdc++.h>
#define MAXN 10001
using namespace std;int n,cnt;//now,xi,yi,xii,yii;
int ans[MAXN];
struct node
{int op;int x,y,k;int xI,yI,xII,yII;
}q[MAXN];
int main()
{scanf("%d",&n);int i=1;while(true){int op;      scanf("%d",&op);if(op==2) scanf("%d%d%d%d",&q[i].xI,&q[i].yI,&q[i].xII,&q[i].yII),q[i].op=2;else if(op==1) scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].k),q[i].op=1;else   break;++i;}for(int j=i-1;j>=1;j--){if(q[j].op==2){int nans=0;for(int r=1;r<j;r++){if(q[r].op==2) continue;if(q[r].x <= q[j].xII && q[r].x >=q[j].xI ){if(q[r].y <= q[j].yII && q[r].y >=q[j].yI ){nans+=q[r].k; }}}ans[++cnt]=nans;}}for(int j=cnt;j>=1;--j){printf("%d\n",ans[j]);}return 0;
}
/*
4
1 2 2 5
1 1 8 1
2 0 0 2 53
*/

T5 数列区间最大值

时间限制: 1 Sec 内存限制: 128 MB

题目描述

输入一串数字,给你 M 个询问,每次询问就给你两个数字 X, Y,要求你说出 X 到 Y 这段区间内的最大数。

输入

第一行两个整数 N,M 表示数字的个数和要询问的次数;
接下来一行为 N 个数;
接下来 M 行,每行都有两个整数 X,Y。

输出

输出共 M 行,每行输出一个数。

样例输入

10 2
3 2 4 5 6 8 1 2 9 7
1 4
3 8

样例输出

5
8

提示

【数据范围与提示】

对于全部数据,1≤N≤105 ,1≤M≤106 ,1≤X≤Y≤N。数字不超过 C/C++ 的 int 范围。

本题其实有不同的做法,但线段树会被卡,或许是因为其查询不是O(1)O(1)O(1) 的(m较大)

故选用ST表,构建O(nlogn)O(nlogn)O(nlogn),查询O(1)O(1)O(1).

#include<iostream>
#include<cstdio>
using namespace std;int lg[100005],a[100005];int f[100005][65];int n,T;int main()
{scanf("%d%d",&n,&T);for(int i=1; i<=n; i++){scanf("%d",a+i);f[i][0]=a[i];}lg[1]=0;for(int j=2; j<=n; j++){lg[j]=lg[j>>1]+1;}int t=lg[n]+1;for(int i=1; i<t; i++){for(int j=1; j<=n-(1<<i)+1; j++){f[j][i]=max(f[j][i-1],f[j+(1<<(i-1))][i-1]);}}for(int i=1; i<=T; i++){int u,v,len;scanf("%d%d",&u,&v);len=v-u+1;t=lg[len];printf("%d\n",max(f[u][t],f[v-(1<<t)+1][t]));}
}

2021-09-22am相关推荐

  1. 橘子CPS联盟操作手册2021.09

    橘子CPS联盟操作手册2021.09 目录 橘子CPS联盟操作手册2021.09 橘子CPS联盟是干嘛的 橘子CPS基本操作流程 PC端操作 1.注册 2.登陆 3.渠道管理 4.分享网站 5.分享网 ...

  2. 2021.09.27 MySQL笔记

    2021.09.27 MySQL笔记 文章目录 2021.09.27 MySQL笔记 一.展示当前存在的所有数据库 二.使用(选中)一个数据库 三.创建一个数据表 四.查询并展示该数据库内的所有数据表 ...

  3. 实习日志 (2021.09.13)

    2021.09.13星期一 今天把之前的算法题终于给弄明白了,并能够按照自己的思路去把他给完成,总结这个题目并不是很难,最重要的是要把链表给弄懂,一开始由于我对链表不是很熟悉,导致我在写该题目的时候花 ...

  4. 2021.09青少年软件编程(Python)等级考试试卷(三级)

    2021.09青少年软件编程(Python)等级考试试卷(三级) 一.单选题(共25题,每题2分,共50分) 1.使用map函数可以实现列表数据元素类型的转换,而无需通过循环.则将列表L=['1',' ...

  5. 2021.09.24—皮皮与帅帅的第二篇情话

    2021.09.24我们小情书的第二天 每天晚上,小兔子都会一个人来到溪水边,坐在地上数着星星.而且他个人也非常喜欢一闪一闪的东西.对于小兔子来说,每颗星星都是特别的,于是她就给每颗星星都起了一个可爱 ...

  6. 《惢客创业日记》2021.09.15(周三)套路的最高境界

    今天,凉粉儿给我发了一段她想的关于惢客的宣传词:"你被套路过吗?想不再被套路吗?上惢客."总结一句话是"不被套路上惢客".我觉得能把惢客跟套路联系在一起,很贴切 ...

  7. Go 1.18将原生支持fuzz test | Gopher Daily (2021.09.21) ʕ◔ϖ◔ʔ

    每日一谚:Clear is better than clever. Go技术生态 Go 1.18合并了对Fuzz测试原生支持的代码 - https://github.com/golang/go/com ...

  8. 2021.09.27-10.3 AI行业周刊(第65期):坚持的力量

    本周话题:坚持的力量 国庆节花费了13个小时,从无锡开车回老家. 原本只需要4个小时,结果生生的开了一天,虽然很累,但是回家乡的执念一直在坚持. 开车回家的一路上,一直在回想这些年坚持做的很多事情: ...

  9. 详解即将于Go 1.18加入的Go泛型特性 | Gopher Daily (2021.09.27) ʕ◔ϖ◔ʔ

    每日一谚:use errors.Is(err, pkg.ErrFoo) rather than err == pkg.ErrFoo. Go技术生态 详解即将于Go 1.18加入的Go泛型特性 - ht ...

  10. Go程序内存泄露问题快速定位 | Gopher Daily (2021.09.01) ʕ◔ϖ◔ʔ

    每日一谚:Less is more. Go技术生态 github针对go仓库提供免费的持续benchmark服务 - https://github.com/marketplace/gobencher ...

最新文章

  1. 【Netty】入门Netty官方例子解析(二)Time Server
  2. 有关EUV光刻机,你需要知道这些
  3. 2005-3-28 + 探索ASP.NET Forum (1) 最初的印象
  4. Django之中间件-CSRF
  5. XVID基本参数解析
  6. 阿里云发布第七代云服务器ECS,整机算力提升160%
  7. 微软 SQL Server 2019 将免费支持 Java;Rancher Labs获2500万美元融资;腾讯云进军日本市场……...
  8. 【Java从入门到头秃专栏 】(一)学在Java语法之前
  9. php pdo总结,php 总结(10) PDO 连接数据库 预处理
  10. 求求你,下次面试别再问我什么是 Spring AOP 和代理了!
  11. day02:关于惯性导航工具箱的学习与使用:use of the progen
  12. 一文简介常见的机器学习算法
  13. JAVA调用U盾进行客户认证实例
  14. idea上传代码到github (图文并茂)
  15. 计算机与手机联网,电脑怎么通过手机共享上网(两种手机和电脑连接上网方法)...
  16. 中国互联网的发展历程
  17. 数值卡,让数据可视化玩出新花样丨三叠云
  18. vue获取列表中的数量_vue.js中列表里面的子元素怎么获取列表的索引index值
  19. vm-install vmware tools安装
  20. 实验 5 递归与列表

热门文章

  1. 显卡驱动安装不了如何解决
  2. windows7家庭普通版(win7 home basic)安装SQL server 2005 开发版
  3. 从业3年45万年薪的AI训练师是如何养成的?
  4. 安全网关与业务网关的区别
  5. 仙剑修改器(VB6)
  6. 李开复给中国大学生的第七封信—21世纪最需要的7种人才
  7. 2021年电工(中级)试题及解析及电工(中级)证考试
  8. webgl图形绘制流程
  9. 字符串图案一键生成网站
  10. 常用的meta标签以及作用