2020杭电多校 2F / HDU 6768 - The Oculus (哈希)
题意
定义为斐波那契数列第项,
已知任意正整数都拥有一个唯一的长度为的数列,使得
以这样的表示法给出三个数
已知数字是由的结果在这样的表示法下将某个原本是的位置改成得来的
问抹去的是哪个位置
数据范围
解
根据数据范围,至少要预处理出前项的斐波那契数列
并通过将值映射回位置
然后根据题目所述,计算出、和的值
其次只要通过来计算出被抹去的数对应的数字是什么,将映射的位置输出即可
想法理解了之后就只剩处理方法的问题了
首先发现数列前项便会超出的范围,所以需要对其进行取模
我们需要保证这个模数能让数列前项在取模后没有冲突(唯一性)
所以需要一个比平时见到的模数更大的模数去尝试(类似这些均有冲突项数)
最后我取了这个模数(若使用可以使用哈希的想法让数自然溢出,应该也是对的)
于是就能预处理+映射求出答案了,详见代码
需要注意的是,模数过大可能会导致计算时超出的范围,所以需要使用快速乘
完整程序(各种优化情况)
由于组数关系及数据范围,所以我们需要考虑应当选取怎样的容器去映射
经(不完全)测试,得到结果如下
容器/读入方式 | 赛时测评(ms) | 题库测评(ms) |
---|---|---|
map + STDIO | / | TLE |
unordered_map + STDIO | 2453 | / |
gp_hash_table + STDIO | 2015 | / |
unordered_map + FastIO | / | 2698 |
gp_hash_table + FastIO | 375 | 1107 |
数据过大,快读这题在题库测评时应该是少不了的
其次稍微提一下,如果提交的是,且需要使用类时
如果空间充足,建议使用来代替,时间复杂度可以降低倍,但空间复杂度会提高倍
在实际使用过程中,除了无法使用函数外,其余与相同
使用方法如下(两个头文件&一个namespace,添加后就能使用了)
下面展示的是组合的程序
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
const int bsz=1<<18;
char bf[bsz],*head,*tail;
inline char gc(){
if(head==tail){
int l=fread(bf,1,bsz,stdin);
tail=(head=bf)+l;
}
return *head++;
}
inline int read(){
int x=0,f=1;
char c=gc();
for(;!isdigit(c);c=gc())
if(c=='-')
f=-1;
for(;isdigit(c);c=gc())
x=x*10+c-'0';
return x*f;
}
inline void write(ll x){
if(x>=10)
write(x/10);
putchar(x%10+'0');
}
inline void putd(ll x)
{
write(x);
putchar('\n');
}
const ll mod=1111111111139LL;
gp_hash_table<ll,int> mp;
ll fibo[2000050];
ll qmul(ll a,ll b){ //快速乘
ll r=0;
while(b){
if(b&1)
r=(r+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return r;
}
void solve()
{
int cnt1,cnt2,cnt3,d;
ll A=0,B=0,C=0;
cnt1=read();
for(int i=1;i<=cnt1;i++)
{
d=read();
if(d==1)
A=(A+fibo[i])%mod;
}
cnt2=read();
for(int i=1;i<=cnt2;i++)
{
d=read();
if(d==1)
B=(B+fibo[i])%mod;
}
cnt3=read();
for(int i=1;i<=cnt3;i++)
{
d=read();
if(d==1)
C=(C+fibo[i])%mod;
}
putd(mp[(qmul(A,B)-C+mod)%mod]);
}
int main()
{
fibo[0]=fibo[1]=1;
mp[1]=1;
for(int i=2;i<=2000010;i++)
{
fibo[i]=(fibo[i-1]+fibo[i-2])%mod;
mp[fibo[i]]=i;
}
int T=read();
while(T--)
solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话