zoukankan      html  css  js  c++  java
  • CF670C 【Cinema】

    题目链接

    退役前发文了。

    排序和离散都是稳定的一只$log$的做法,这里给大家介绍一种玄学复杂度的数据结构,$hash$表。

    $hash$表的思想很简单,将所有对$mod$取模在一个同余类的数用链表串起来 (不要告诉我你不会链表),这样时间复杂度就依赖于$mod$大小。**理论上来说**,$mod$越大,同余类的冲突越小,跑得就快些;$mod$越小,每个同余类里聚集的数较多,跑得就慢些。我们往往需要找到那个空间和时间上的平衡点。

    经实测,本题的较优$mod$是$1e6$,还有一个小优化,就是对于小于$mod$的数,单独开桶来记,但影响不大。

    解决了本题的瓶颈,其他地方就不细讲了。

    本题解卡了下常,拿到了$rank 1$(但估计很快就死了QwQ),$rank 2$是我们机房的一个奆奆,他的$mod$是$1e6+7$,但没有加那个小优化。

    #include<iostream>
    #include<iomanip>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define INF 0x3f3f3f3f
    inline char gc(){
        static char buf[100000],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int read(){
        char ch;
        int bj=1;
        while(!isdigit(ch=gc()))
          bj=(ch=='-')?-1:1;
        int res=ch^(3<<4);
        while(isdigit(ch=gc()))
          res=(res<<1)+(res<<3)+(ch^(3<<4));
        return res*bj;
    }
    void printnum(int x){
        if(x>9)printnum(x/10);
        putchar(x%10+'0');
    }
    inline void print(int x,char ch){
        if(x<0){
            putchar('-');
            x=-x;
        }
        printnum(x);
        putchar(ch);
    }
    const int mod=1e6;
    int to[200000],v[200000],nxt[200000],h[mod],cnt;
    int n,m,a[200005],b[200005],t[mod];
    int maxn1=-INF,maxn2=-INF,ans;
    inline void Insert(int x){
        if(x<mod){
            t[x]++;
            return;
        }
        for(int i=h[x%mod];i;i=nxt[i])
            if(to[i]==x){
                v[i]++;
                return;
            } 
        to[++cnt]=x;
        v[cnt]=1;
        nxt[cnt]=h[x%mod];
        h[x%mod]=cnt;
    }
    inline int query(int x){
        if(x<mod)return t[x];
        for(int i=h[x%mod];i;i=nxt[i])
            if(to[i]==x)return v[i];
        return 0;
    }
    signed main(){
        n=read();
        int x;
        while(n--)x=read(),Insert(x);
        m=read();
        for(int i=1;i<=m;i++)a[i]=read();
        for(int i=1;i<=m;i++)b[i]=read();
        for(int i=1;i<=m;i++){
            int tmp1=query(a[i]),tmp2=query(b[i]);
            if(tmp1>maxn1){
                maxn1=tmp1;
                maxn2=tmp2;
                ans=i;
            }
            else if(tmp1==maxn1&&tmp2>maxn2){
                maxn1=tmp1;
                maxn2=tmp2;
                ans=i;
            }
        }
        print(ans,'
    ');
        return 0;
    }
  • 相关阅读:
    C# Lambda表达式 (转)
    用C#读取txt文件的方法(转)
    c#中stringbuilder的使用(转)
    c# 日期和时间的获取(转)
    C# List<T>用法 泛型 (转)
    indent format codes
    格式化输入输出 小结
    putty connection manager 一些问题的整理
    linux 网络的一些书籍
    Oracle学习笔记
  • 原文地址:https://www.cnblogs.com/soledadstar/p/11632250.html
Copyright © 2011-2022 走看看