2018-10-14普及模拟赛」Hash 键值 (hash)
今天,带大家看一看一道思维题。。。
Hash 键值 (hash)
题目描述
Marser沉迷hash无法自拔,然而他发现自己记不住hash键值了……
Marser使用的hash函数是一个单纯的取模运算,每一个数i被对应到i mod p。他现在有一个数列,他采用这种方法,把每一个数对应到一个键值i mod p。他想知道对于给定的模数p和键值r,所有对应到该键值的数的和为多少。同时,Marser可能会发现他的数列出了一些问题,所以他还想随时更改数列中任意一项的值。
现在Marser有q个请求,每个请求可能是修改或是询问。对于每一个询问,你需要给出正确的答案。如果你不能在1s内正确回答所有询问,Marser就会让hotwords把你给续了。
输入格式
从文件hash.in读入。
第一行两个整数n,q,表示数列长度和请求数量。
第二行n个整数,表示初始的序列。
接下来m行,每行三个整数opt,x,y;
若opt=1,则询问在mod x时,所有对应到键值y的数的和。
若opt=2,则将数列第x项修改为y。
输出格式
输出到文件hash.out中。
样例
样例输入 1
10 5
1 2 3 4 5 6 7 8 9 10
1 2 1
2 1 20
1 3 1
2 5 1
1 5 0
样例输出 1
25
41
11
首先,我们发现这是一道水题
轻轻松松写下下面的代码
#include <bits/stdc++.h>
using namespace std;
int a[100005];
int main() {
int n, m;
freopen("hash.in","r",stdin);
freopen("hash.out","w",stdout);//文件输入输出
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for (int i = 1; i <= m; ++i) {
int x;
scanf("%d", &x);
if (x == 1) {
int x1, x2, ans = 0;
scanf("%d%d", &x1, &x2);
for (int i = x2; i <= n; i += x1) { //不需要一个一个枚举,只需要算x1的倍数就行了;
ans += a[i];
}
printf("%d\n", ans);
}
if (x == 2) {
int x1, x2;
scanf("%d%d", &x1, &x2);
a[x1] = x2; //维护
}
}
}
然后我们发现:
轻轻松松超时
竟然可以拿30分!!!
咳咳,言归正传,我们开始讨论100分的代码
(开始吟唱)
Frist:
我们需要算一下时间复杂度
原代码时间复杂度为O(n+mn/x1);
所以我们的代码一定要小于这个时间复杂度;
second
我们发现,无论如何原代码的时间复杂度是减少不了的了至少我没想出啦。。。,所以只能:
另辟蹊径:
仔细一想,不难得出:如果我们能在x1,x2读入的时候,就直接输出ans,那么时间复杂度肯定会大大降低;
那么我们怎么才可以实现这种操作呢?
首先,定义一个名为sum的二维数组,sum[i][j]表示所有模i余j的数的总和;
再输入一个a[i]以后,就用一重循环遍历,代码如下:
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
for(int j=1;j<n;++j){
sum[j][i%j]+=a[i]; //除j模(i%j);
}
}
这样,我们其实就可以达成输入就输出啦!!!
但我们再来算算时间复杂度O=(nn+mn)(为什么是mn呢?因为当我们更改一个值时,那么sum数组的之也要改);
然后我们神奇的发现,时间复杂度竟然比原来还大!
那么,如果我们不遍历所有值,而是只遍历log(n),再把x1>log(n)的情况用第一种方法运算呢???
再算算时间复杂度:O=(n*log(m)+MAX(mn/x1,mn));
化简一下:O=(n*log(m)+mn/x1);
然后我们就可以过剩下的测试点啦!!!
上代码!!!:
再次声明:如果你要抄代码,只会害了你自己。。。
#include<bits/stdc++.h>
using namespace std;
int a[1000005],sum[1005][1005]; //sum[i][j]等于所有除以i余j的数的和;
int main(){
freopen("hash.in","r",stdin);
freopen("hash.out","w",stdout); //文件输入输出
int n,m;
scanf("%d%d",&n,&m);
int num=sqrt(n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
for(int j=1;j<num;j++){
sum[j][i%j]+=a[i]; //对sum进行赋值,循环j模拟i除以的数之和;
}
}
for(int i=1;i<=m;++i){
int x;
scanf("%d",&x);
if(x==1){
int x1,x2,ans=0;
scanf("%d%d",&x1,&x2);
if(x1<num){//如果x1<num,说明x1在sum处理的范围内;
printf("%d\n",sum[x1][x2]); //直接通过前文对sum的处理输出;
}
else{
for(int i=x2;i<=n;i+=x1){ //方法一;
ans+=a[i];
}
printf("%d\n",ans);
}
}
if(x==2){
int x1,x2;
scanf("%d%d",&x1,&x2);
for(int i=1;i<=num;i++)
sum[i][x1%i]=sum[i][x1%i]-a[x1]+x2; //维护sum数组,把a[x1]覆盖成x2,并确保sum里的值正确;
a[x1]=x2; //对a[i]也要进行维护;
}
}
}
2018-10-14普及模拟赛」Hash 键值 (hash)的更多相关文章
- 2018.10.16 NOIP模拟赛解题报告
心路历程 预计得分:\(100 + 100 + 20 = 220\) 实际得分:\(100 + 100 + 30 = 230\) 辣鸡模拟赛.. T1T2都是一眼题,T3考验卡常数还只有一档暴力分. ...
- 2018.10.29 NOIP2018模拟赛 解题报告
得分: \(70+60+0=130\)(\(T3\)来不及打了,结果爆\(0\)) \(T1\):简单的求和(点此看题面) 原题: [HDU4473]Exam 这道题其实就是上面那题的弱化版,只不过把 ...
- 2018.10.03 NOIP+ 模拟赛 解题报告
得分: \(30+5+0=35\)(考得真不咋滴) \(T1\):奥义商店(点此看题面) 以为很简单,对着这题想了一个多小时,最后果断打了个暴力交了... ... 看完题解发现其实也不是很难. 对于\ ...
- 2018.10.26 NOIP2018模拟赛 解题报告
得分: \(0+10+10=20\)(\(T1\)死于假题面,\(T3\)死于细节... ...) \(P.S.\)由于原题是图片,所以我没有上传题目描述,只有数据. \(T1\):颜料大乱斗(点此看 ...
- 2018.10.24 NOIP2018模拟赛 解题报告
得分: \(100+0+100=200\)(\(T2\)悲惨爆\(0\)) \(P.S.\)由于原题是图片,所以我没有上传题目描述,只有数据. \(T1\):query(点此看题面) 熟悉主席树的人都 ...
- 2018.10.30 NOIp模拟赛 T1 改造二叉树
[题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他又和他人讨论 ...
- 2018.10.17校内模拟赛:T2神光
题面:pdf 首先排序,二分,然后怎么判定是否可行. 最简单的思路是,dp[i][j][k],到第i个,用了j次红光,k次绿光,前i个点都选上了,是否可行.然后转移就行. 然后考试的时候就想到这了,往 ...
- 2018.10.30 NOIp模拟赛T2 数字对
[题目描述] 小 H 是个善于思考的学生,现在她又在思考一个有关序列的问题. 她的面前浮现出一个长度为 n 的序列{ai},她想找出一段区间[L, R](1 <= L <= ...
- 10.17 NOIP模拟赛
目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...
随机推荐
- Select Screen 0 with xrandr Ask QuestionScreen 0" here describes your whole virtual display made of these two outputs: eDP-1-
Screen 0" here describes your whole virtual display made of these two outputs: eDP-1-1: physica ...
- CPU缓存是位于CPU与内存之间的临时数据交换器,它的容量比内存小的多但是交换速度却比内存要快得多。CPU缓存一般直接跟CPU芯片集成或位于主板总线互连的独立芯片上
一.什么是CPU缓存 1. CPU缓存的来历 众所周知,CPU是计算机的大脑,它负责执行程序的指令,而内存负责存数据, 包括程序自身的数据.在很多年前,CPU的频率与内存总线的频率在同一层面上.内存的 ...
- OpenStack常见面试题
现在,大多数公司都试图将它们的 IT 基础设施和电信设施迁移到私有云, 如 OpenStack.如果你打算面试 OpenStack 管理员这个岗位,那么下面列出的这些面试问题可能会帮助你通过面试. Q ...
- Spring AOP 框架
引言 要掌握 Spring AOP 框架,需要弄明白 AOP 的概念. AOP 概念 AOP(Aspect Oriented Programming的缩写,翻译为面向方面或面向切面编程),通过预编译方 ...
- 重新整理 .net core 实践篇————依赖注入应用之生命法则[三]
前言 该章演示依赖注入中,对象的释放行为. 紧接上文表示,演示: services.AddSingleton<IMySingletonService, MySingletonService> ...
- 【Web前端HTML5&CSS3】12-字体
笔记来源:尚硅谷Web前端HTML5&CSS3初学者零基础入门全套完整版 目录 字体 1. 字体相关的样式 2. font-family 3. 几种字体 手写体 艺术体 乱码字体 中文字体 4 ...
- idea开发web项目框架失效和无法启动问题
不会配置idea的javaweb环境的小伙伴可以点击此链接 idea最新版,配置javaweb环境 很多小伙伴用idea开发web项目可能会出现所有代码都写对了但是无论如何都没法运行的情况,eclip ...
- 使用shell脚本循环处理文本
公司是使用puppet来进行配置管理, 某天修改完puppet后领导回复: 我们有一个文档cabinet.txt记录了物理机器所在的机柜, 除了文档里的其他机器都是虚拟机或云服务器, 对虚拟机的pup ...
- TVM交叉编译和远程RPC
TVM交叉编译和远程RPC 本文介绍了TVM中使用RPC的交叉编译和远程设备执行. 使用交叉编译和RPC,可以在本地计算机上编译程序,然后在远程设备上运行它.当远程设备资源受到限制时(如Raspber ...
- TensorFlow文本情感分析实现
TensorFlow文本情感分析实现 前面介绍了如何将卷积网络应用于图像.本文将把相似的想法应用于文本. 文本和图像有什么共同之处?乍一看很少.但是,如果将句子或文档表示为矩阵,则该矩阵与其中每个单元 ...