HDU - 6768 The Oculus(哈希)

传送门


看到斐波那契数列,以为是矩阵或者公式那种题,但是本题给出的位数太大,一时间没想到怎么写,赛后题解说是哈希才恍然大悟,看来还是自己对哈希不太熟练(还有一个重要原因是这个复杂度遍历竟然不超时,这是无论如何都想不到的)

正解:

令修改的那一位为 k k ,则要找到这个 k k 满足 A × B = C + F ( k ) A×B = C+F(k) ,因为斐波那契数列第几十项以后就爆 l o n g    l o n g   long~~long~ 了,那么需要哈希,题解给的是自然溢出哈希,然后我看这篇博客也学到了很多,包括快读优化以及 g p _ h a s h _ t a b l e gp\_hash\_table 代替 u n o r e d e r e d _ m a p unoredered\_map

但是本题还是有不解:如果使用自然溢出哈希+ m a p map 怎么优化都超时,除非遍历找答案;使用单模数哈希却不会

从大佬那里学到的

#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define Vector Point
#define lowbit(x) (x&(-x))
#define mkp(x,y) make_pair(x,y)
#define mem(a,x) memset(a,x,sizeof a);
#pragma GCC optimize(3)
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const double dinf=1e300;
const ll INF=1e18;
const ll Mod=1111111111139LL;
const int maxn=2e6+10;

ll f[maxn];
unordered_map<ll,int> mp;

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');
}

void init(){
    mp[1]=1,mp[2]=2;
    f[1]=1,f[2]=2;
    for(int i=3;i<maxn;i++){
        f[i]=(f[i-1]+f[i-2])%Mod;
        mp[f[i]]=i;
    }
}

ll qkm(ll a,ll b){
    ll ans=0;
    while(b){
        if(b&1) ans=(ans+a)%Mod;
        a=(a+a)%Mod;
        b>>=1;
    }
    return ans;
}

int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    //ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t,A,B,C;
    init();
    t=read();
    while(t--){
        ll a=0,b=0,c=0;
        A=read();
        for(int i=1,x;i<=A;i++){
            x=read();
            if(x) a=(a+f[i])%Mod;
        }
        B=read();
        for(int i=1,x;i<=B;i++){
            x=read();
            if(x) b=(b+f[i])%Mod;
        }
        C=read();
        for(int i=1,x;i<=C;i++){
            x=read();
            if(x) c=(c+f[i])%Mod;
        }
        ll ans=(qkm(a,b)-c+Mod)%Mod;
        putd(mp[ans]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44691917/article/details/107598656