【Violet 6】【BZOJ2724】蒲公英

来源:互联网 发布:宁波淘宝运营高手 编辑:程序博客网 时间:2024/04/28 07:53

Description
这里写图片描述
Input
这里写图片描述
修正一下

l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1
Output
这里写图片描述
Sample Input
6 3
1 2 3 2 1 2
1 5
3 6
1 5
Sample Output
1
2
1
HINT

这里写图片描述
修正下:

n <= 40000, m <= 50000

Source

Vani原创

区间众数.
想了一段时间线段树感觉不科学T_T
观察数据范围也不像线段树啊…
然后去感受了一下发现是分块…
跟着黄学长领悟了人生第一个分块…(求不D

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXN 40010#define GET (ch>='0'&&ch<='9')using namespace std;int n,m,size,cnt,maxn,Ans,lastans;int a[MAXN],belong[MAXN],first[300],last[300],Count[MAXN];int hash[MAXN],L[MAXN],R[MAXN];int ans[300][300];//块间答案 struct Num{    int pos,x;    bool operator <(const Num& a)const  {return x==a.x?pos<a.pos:x<a.x;}}s[MAXN];void in(int &x){    char ch=getchar();x=0;    while (!GET)    ch=getchar();    while (GET) x=x*10+ch-'0',ch=getchar();}int find(int x){    int l=1,r=n,mid;    while (l<=r)    {        mid=(l+r)>>1;        if (hash[mid]<x)    l=mid+1;        else    if (hash[mid]>x)    r=mid-1;        else    return mid;    }}int upper(int l,int r,int x)//不会用STL星人 {    int ret=0,mid;    while (l<=r)    {        mid=(l+r)>>1;        if (s[mid].pos>x)   r=mid-1;        else    ret=mid,l=mid+1;    }    return ret;}int lower(int l,int r,int x){    int ret=0,mid;    while (l<=r)    {        mid=(l+r)>>1;        if (s[mid].pos<x)   l=mid+1;        else    ret=mid,r=mid-1;    }    return ret;}int query(int l,int r){    int ret;maxn=0;    if (belong[l]==belong[r])    {        for (int i=l;i<=r;i++)        {            int Cnt=upper(L[a[i]],R[a[i]],r)-lower(L[a[i]],R[a[i]],l)+1;            if (Cnt>maxn||(Cnt==maxn&&a[i]<ret))    maxn=Cnt,ret=a[i];        }        return ret;    }    if (belong[l]+1<belong[r])  ret=ans[belong[l]+1][belong[r]-1],maxn=upper(L[ret],R[ret],r)-lower(L[ret],R[ret],l)+1;    for (int i=l;i<=last[belong[l]];i++)    {        int Cnt=upper(L[a[i]],R[a[i]],r)-lower(L[a[i]],R[a[i]],l)+1;        if (Cnt>maxn||(Cnt==maxn&&a[i]<ret))    maxn=Cnt,ret=a[i];    }    for (int i=first[belong[r]];i<=r;i++)    {        int Cnt=upper(L[a[i]],R[a[i]],r)-lower(L[a[i]],R[a[i]],l)+1;        if (Cnt>maxn||(Cnt==maxn&&a[i]<ret))    maxn=Cnt,ret=a[i];    }    return ret;}int main(){    in(n);in(m);size=(int)(sqrt(n));cnt=n/size+(bool)(n%size);//划分块     for (int i=1;i<=n;i++)  in(a[i]),hash[i]=a[i],belong[i]=(i-1)/size+1;    for (int i=1;i<=cnt;i++)    first[i]=size*(i-1)+1,last[i]=size*i;    sort(hash+1,hash+n+1);    for (int i=1;i<=n;i++)  a[i]=find(a[i]);//离散     for (int i=1;i<=n;i++)  s[i].x=a[i],s[i].pos=i;    sort(s+1,s+n+1);int l,r;    for (int i=1;i<=n;i++)//记录每个数出现左右区间     {        if (!L[s[i].x]) L[s[i].x]=i;        R[s[i].x]=i;    }    for (int i=1,t;i<=cnt;i++)    {        memset(Count,0,sizeof(Count));maxn=0;        for (int j=first[i];j<=n;j++)        {            Count[a[j]]++;            if (Count[a[j]]>maxn||(Count[a[j]]==maxn&&a[j]<t))  maxn=Count[a[j]],t=a[j];            ans[i][belong[j]]=t;        }    }    for (int i=1;i<=m;i++)    {        in(l);in(r);l=(l+lastans-1)%n+1;r=(r+lastans-1)%n+1;        if (l>r)    swap(l,r);        Ans=hash[query(l,r)];lastans=Ans;        printf("%d\n",Ans);    }}
0 0
原创粉丝点击