不是妹子,不开O2 只有25分

P4168 [Violet] 蒲公英

mendessy @ 2019-10-08 09:34:16

可是我也是分块啊。我jio的我的复杂度是对的,有没有神仙来帮忙卡一卡常啊


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#define int long long 
using namespace std;
const int maxn=40010;
const int maxm=250;
const int inf=0x3f3f3f3f;
int bl[maxn],n,m,sqrtn;
int l,r,x,a[maxn],lsh[maxn],ls;
int f[maxm][maxm],num[maxn];//f[i][j]表示i-j块中出现次数最多的数字 
int maxbl;
vector<int> pos[maxn];
int read()
{
    int 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;
}

inline void prepare_work()//预处理f数组 
{
    for(int i=1;i<=maxbl;i++)
    {
        for(int j=1;j<=n;j++)   num[j]=0;
        int mode=inf,maxnum=0;
        for(int j=(i-1)*sqrtn+1;j<=n;j++)
        {
            num[a[j]]++;
            if(num[a[j]]>maxnum || (num[a[j]]==maxnum && a[j]<mode))
            {
                maxnum=num[a[j]];   //maxnum表示当前某数字出现的最多次数 
                mode=a[j];   //mode表示出现次数最多的数字的最小值 
            }
            f[i][bl[j]]=mode;
        }
    }

}

int getnum(int l,int r,int x)//找l-r区间内x的数量 
{
    int t=upper_bound(pos[x].begin(),pos[x].end(),r)-lower_bound(pos[x].begin(),pos[x].end(),l);
    return t;
}

int query(int l,int r)//查询操作 
{
    int maxnum=0,mode=inf;
    for(int i=l;i<=min(r,bl[l]*sqrtn);i++)
    {
        int tot=getnum(l,r,a[i]);
        if(tot>maxnum || (tot==maxnum && mode>a[i]))
        {
            maxnum=tot;
            mode=a[i];
        }
    }
    if(bl[l]!=bl[r])
    {
        for(int i=(bl[r]-1)*sqrtn+1;i<=min(r,bl[r]*sqrtn);i++)
        {
            int tot=getnum(l,r,a[i]);
            if(tot>maxnum || (tot==maxnum && mode>a[i]))
            {
                maxnum=tot;
                mode=a[i];
            }
        }
    }
    if(bl[l]+1<=bl[r]-1)
    {
        int tot=getnum(l,r,f[bl[l]+1][bl[r]-1]);
        if(tot>maxnum || (tot==maxnum && mode>f[bl[l]+1][bl[r]-1]))
        {
            maxnum=tot;
            mode=f[bl[l]+1][bl[r]-1];
        }
    }
    return mode;
}

signed main(){
//  freopen("fenkuai.in","r",stdin);
//  freopen("own.out","w",stdout);
    n=read();m=read();
    sqrtn=sqrt(n);
    for(int i=1;i<=n;i++)
        a[i]=lsh[i]=read();
    sort(lsh+1,lsh+1+n);
    ls=unique(lsh+1,lsh+1+n)-lsh-1;
    for(int i=1;i<=n;i++)
        a[i]=lower_bound(lsh+1,lsh+1+ls,a[i])-lsh;
    for(int i=1;i<=n;i++)
    {
        bl[i]=(i-1)/sqrtn+1;
        pos[a[i]].push_back(i);//存储相同的数的pos在同一个数组中 
    }   
    maxbl=(n-1)/sqrtn+1;//表示最大块编号 
    prepare_work();
    for(int i=1;i<=m;i++)
    {
        l=read();r=read();
        l=(l+x-1)%n+1;
        r=(r+x-1)%n+1;
        if(l>r)
            swap(l,r);
        printf("%lld\n",x=lsh[query(l,r)]);
    }
    return 0;
}

by VeritasatireV @ 2019-10-08 10:30:04

OrzOrz 卡常找earringyyr, 她一定会帮你卡不过的。


|