# 【BZOJ2724】蒲公英（分块）

## 题解

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 40040
const int m=30;
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,Q,blk,a[MAX],b[MAX];
int S[MAX],tot,num[MAX];
vector<int> p[MAX];
int f[1500][1500];
int Calc(int x,int l,int r)
{
if(p[x].size()==0)return 0;
int L,R,ret1,ret2;
L=0,R=p[x].size()-1,ret1=R;
while(L<=R)
{
int mid=(L+R)>>1;
if(p[x][mid]>=l)ret1=mid,R=mid-1;
else L=mid+1;
}
L=0,R=p[x].size()-1,ret2=L;
while(L<=R)
{
int mid=(L+R)>>1;
if(p[x][mid]<=r)ret2=mid,L=mid+1;
else R=mid-1;
}
return max(ret2-ret1+1,0);
}
int main()
{
sort(&S[1],&S[n+1]);tot=unique(&S[1],&S[n+1])-S-1;
for(int i=1;i<=n;++i)a[i]=lower_bound(&S[1],&S[tot+1],a[i])-S;
for(int i=1;i<=n;++i)p[a[i]].push_back(i);
for(int i=1;i<=n;++i)b[i]=(i-1)/m+1;
for(int i=1;i<=blk;++i)
{
memset(num,0,sizeof(num));
int x=0;
for(int k=i;k<=blk;++k)
{
for(int j=(k-1)*m+1;j<=n&&j<=k*m;++j)
{
num[a[j]]++;
if(num[a[j]]>num[x]||(num[a[j]]==num[x]&&x>a[j]))x=a[j];
}
f[i][k]=x;
}
}
int ans=0;
while(Q--)
{
if(l>r)swap(l,r);
int mx=0,x=0;
if(b[l]==b[r])
for(int i=l;i<=r;++i)
{
int d=Calc(a[i],l,r);
if(d>mx||(d==mx&&x>a[i]))mx=d,x=a[i];
}
else
{
x=f[b[l]+1][b[r]-1];mx=Calc(x,l,r);
for(int i=l;i<=n&&(i==l||i%m!=1);++i)
{
int d=Calc(a[i],l,r);
if(d>mx||(d==mx&&x>a[i]))mx=d,x=a[i];
}
for(int i=r;i>=1&&(i==r||i%m!=0);--i)
{
int d=Calc(a[i],l,r);
if(d>mx||(d==mx&&x>a[i]))mx=d,x=a[i];
}
}
printf("%d\n",ans=S[x]);
}
return 0;
}


posted @ 2018-09-18 20:42  小蒟蒻yyb  阅读(496)  评论(1编辑  收藏  举报