zoukankan      html  css  js  c++  java
  • LOJ #6285 分块入门9

    题意:区间众数,不带修改,带修改刚看了一眼没看懂cls在讲啥QAQ。

    题解:按照代码中那个sqrt(n/2/log2(n))大小分块,可以用均值不等式证明的,就是假设查询和n同级,然后一通爆算就可以得出了。然后预处理出(i,j)块之间最多的数。然后不满一块的部分在vector上二分,这题要先离散化。PS:loj上可以看别人代码学习速度++ 啊。因为把hzwer的1-9看了一遍,时间有限,就随便挑一个了,然后bzoj上的题是权限题,就注册了loj找了份简洁的学着写了,不太习惯,然后有更优秀的做法,看hzwer博客以及cls的论文吧,如果这样预处理直接sqrt(n)是TLE的,应该是卡掉了。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=1e5+7;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m;
    vector<int >vec[maxn];
    int gs(int x,int l,int r)
    {
        return upper_bound(vec[x].begin(),vec[x].end(),r)-lower_bound(vec[x].begin(),vec[x].end(),l);
    }
    int a[maxn],b[maxn],bl[maxn];
    int f[2000][2000];
    int s[maxn];
    int get(int l,int r)
    {
        if(bl[l]==bl[r])
        {
            int ans=0,ans1=0;
            for(int i=l;i<=r;i++)
            {
                int tmp=gs(a[i],l,r);
                if(tmp>ans1){
                    ans=a[i];ans1=tmp;
                }
                if(tmp==ans1)ans=min(a[i],ans);
            }
            return ans;
        }
        int ans0=f[bl[l]+1][bl[r]-1],ans1=gs(ans0,l,r);
        for(int i=l;bl[i]==bl[l];i++)
        {
            int tmp=gs(a[i],l,r);
            if(tmp>ans1)
            {
                ans0=a[i];ans1=tmp;
            }
            if(tmp==ans1)ans0=min(a[i],ans0);
        }
        for(int i=r;bl[i]==bl[r];i--)
        {
            int tmp=gs(a[i],l,r);
            if(tmp>ans1)ans0=a[i],ans1=tmp;
            if(tmp==ans1)ans0=min(a[i],ans0);
        }
        return ans0;
    }
    int main()
    {
        n=read();
        int d=(int)sqrt(n/2/log2(n));
        for(int i=1;i<=n;i++)
        {
            a[i]=read();b[i]=a[i];bl[i]=(i-1)/d+1;
        }
        sort(b+1,b+1+n);
        int ts=unique(b+1,b+1+n)-b-1;
        for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+1+ts,a[i])-b;
        for(int i=1;i<=n;i++) vec[a[i]].push_back(i);
        for(int i=1;i<=bl[n];i++)
        {
            memset(s,0,sizeof(s));
            int ans1=0,ans2=0;
            for(int j=(i-1)*d+1;j<=n;j++)
            {
                s[a[j]]++;
                if(s[a[j]]==ans2)
                {
                    ans1=min(a[j],ans1);
                }
                else if(s[a[j]]>ans2)
                {
                    ans1=a[j];ans2=s[a[j]];
                }
                if(bl[j+1]!=bl[j])
                    f[i][bl[j]]=ans1;
            }
        }
        int p=0,q=0;
        for(int i=1;i<=n;i++)
        {
            p=read();q=read();
            if(p>q)swap(p,q);
            cout<<b[get(p,q)]<<"
    ";
        }
    }
    

      

  • 相关阅读:
    洛谷p1017 进制转换(2000noip提高组)
    Personal Training of RDC
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Eurasia
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof.
    Asia Hong Kong Regional Contest 2019
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Siberia
    XVIII Open Cup named after E.V. Pankratiev. Ukrainian Grand Prix.
    XVIII Open Cup named after E.V. Pankratiev. GP of SPb
    卜题仓库
    2014 ACM-ICPC Vietnam National First Round
  • 原文地址:https://www.cnblogs.com/intwentieth/p/9855370.html
Copyright © 2011-2022 走看看