给出一个长度为n的序列a[]
给出q组询问,每组询问形如
其实打一个不要太暴力的暴力即可,
暴力的暴力是一位一位的跳,把它改成跳到下一个相同的即可,
一样的询问用哈希判断啦,
复杂度: O(n2)
//所以你们跑得都比我快的原因是你们不用MAP咯~
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define min(q,w) ((q)>(w)?(w):(q))
#define max(q,w) ((q)<(w)?(w):(q))
using namespace std;
const int N=8500,INF=2147483640;
int read(int &n)
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int m,n,ans;
map<int,int>Ans,bh;
int a[N],zx[N],nm[N];
int z[N*2][2],TI;
int main()
{
freopen("query.in","r",stdin);
freopen("query.out","w",stdout);
int q,w;
read(n),read(m);
w=0;
fo(i,1,n)
{
read(q);
int t=bh[q];
zx[i]=t;
a[i]=(t?a[t]:(++w));
bh[q]=i;
nm[a[i]]++;
}
fo(I,1,m)
{
read(q),read(w);
q=bh[q],w=bh[w];
if(q==w){printf("%d\n",n*(n+1)/2);continue;}
if(q>w)swap(q,w);
if(nm[a[q]]>nm[a[w]])swap(q,w);
int Q=q,W=w;
if(Ans[q*(n+1)+w]){printf("%d\n",Ans[q*(n+1)+w]);continue;}
TI++;
int t=0,t1=0;
z[n][1]=TI,z[n][0]=n+1-max(q,w);
ans=z[n][0]*(z[n][0]-1)/2;
for(;q||w;)
{
if(q>w)
{
int nx=q-max(zx[q],w);
t++;
int j=n+t-t1;
if(z[j][1]1]=TI,z[j][0]=0;
ans+=z[j][0]*nx+(nx-1)*nx/2;
z[j][0]+=nx;
q=zx[q];
}else
{
int nx=w-max(zx[w],q);
t1++;
int j=n+t-t1;
if(z[j][1]1]=TI,z[j][0]=0;
ans+=z[j][0]*nx+(nx-1)*nx/2;
z[j][0]+=nx;
w=zx[w];
}
}
Ans[Q*(n+1)+W]=ans;
printf("%d\n",ans);
}
return 0;
}