查询
Description
给出一个长度为
n
的序列
Data Constraint
1
<=
Solution
先对所有的数离散化。
先处理掉特殊情况:
x
,
然后考虑怎么预处理询问(
但这样做的缺点在于每次都要重新
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define fo(i,j,l) for(int i=j;i<=l;i++)
#define fd(i,j,l) for(int i=j;i>=l;i--)
using namespace std;
typedef long long ll;
const ll N=8e3+4e2,M=68e4,K=100;
struct note{
int x,w,k;
}px[N+M*2];
int xw[M][2],n,m,j,k,l,i,o,q,a[N],num[M],b[M],e[M],d[M],r[N];
int ans[N][N],lj[2*N],bh[2*N],dq;
int read()
{
int o=0; char ch=' ';
for(;ch<'0'||ch>'9';ch=getchar());
for(;ch>='0'&&ch<='9';ch=getchar())o=o*10+ch-48;
return o;
}
void pri(int o)
{
if(o==0)return;else pri(o/10);
putchar('0'+o%10);
}
void write(int o)
{
if(o==0)putchar('0');
else pri(o);
putchar('\n');
}
bool ksm(note a,note b)
{return a.x<b.x;}
bool ksm2(note a,note b)
{return a.x!=b.x ? a.x<b.x : a.w<b.w ;}
int count(int x,int y)
{
int an=0;dq++;
int k1=b[x],k2=b[y],e1=e[x],e2=e[y];
int f=0,g=0,last=0,now,len=e1+e2-k1-k2+2;
fo(i,1,len){
if((px[k1].w<px[k2].w&&k1<=e1)||k2>e2){
now=px[k1++].w;
if(now>last)an+=(now-last)*(now-last-1)/2;
if(bh[f-g+n]!=dq)bh[f-g+n]=dq,lj[f-g+n]=0;
if(now>last)an+=(now-last)*lj[f-g+n];
lj[f-g+n]+=now-last;
f++;
last=now;
}else{
now=px[k2++].w;
if(now>last)an+=(now-last)*(now-last-1)/2;
if(bh[f-g+n]!=dq)bh[f-g+n]=dq,lj[f-g+n]=0;
if(now>last)an+=(now-last)*lj[f-g+n];
lj[f-g+n]+=now-last;
g++;
last=now;
}
}
if(last<=n)an+=(n-last)*(n-last+1)/2;
if(bh[f-g+n]!=dq)bh[f-g+n]=dq,lj[f-g+n]=0;
if(last<=n)an+=(n-last+1)*lj[f-g+n];
return an;
}
int tj(int o)
{
int last=0,kk=0;
fo(i,b[o],e[o]){
if(last+1<px[i].w)kk+=(px[i].w-last)*(px[i].w-last-1)/2;
last=px[i].w;
}
if(last<n)kk+=(n-last)*(n-last+1)/2;
return kk;
}
int main()
{
n=read(); q=read();
fo(i,1,n)px[i].x=read(),px[i].w=0,px[i].k=i;
fo(i,1,q){
px[i*2+n-1].x=read(),px[i*2+n-1].w=1,px[i*2+n-1].k=i*2-1;
px[i*2+n].x=read(),px[i*2+n].w=1,px[i*2+n].k=i*2;
}
sort(px+1,px+(n+2*q)+1,ksm);
px[0].x=0; int kk=0;
fo(i,1,n+2*q){
kk+=(px[i].x!=px[i-1].x);
if(!px[i].w)a[px[i].k]=kk;
else xw[(px[i].k+1)/2][!(px[i].k%2>0)]=kk;
}
fo(i,1,n)px[i].x=a[i],px[i].w=i;
sort(px+1,px+n+1,ksm2);
int v=0;
fo(i,1,n){
if(px[i].x!=px[i-1].x)d[px[i].x]=++v,b[v]=i;
num[a[i]]++;
e[v]=i;
}
fo(i,1,v-1)fo(l,i+1,v)ans[i][l]=ans[l][i]=count(i,l);
fo(i,1,v)r[i]=tj(i),ans[i][i]=n*(n+1)/2;
int gd=n*(n+1)/2;
fo(i,1,q){
int u=xw[i][0],v=xw[i][1];
if((num[u]|num[v])==0)write(gd);
else if(num[u]==0)write(r[d[v]]);
else if(num[v]==0)write(r[d[u]]);
else write(ans[d[v]][d[u]]);
}
}