题目
求出块内的,跨块的,最后还有散对散的。
全部都可以
O
(
n
n
)
O(n\sqrt n)
O(nn)
具体看代码吧,无力.jpg
为啥分块最后一块的大小不是S啊。
调了3h。
AC Code:
#include<bits/stdc++.h>
#define maxn 50005
#define S 250
using namespace std;
int n,a[maxn],sb[maxn],sa[maxn];
int ans1[S+5][S+5][S+5],bl[maxn];//in block
int ans2[S+5][maxn];//block to pt!s!
int cnt1[maxn];//while
int cnt2[S+5][S+5];//in block
int sbl[S+5],ebl[S+5];
inline bool cmp(const int &u,const int &v){ return a[u]==a[v]?u<v:a[u]<a[v]; }
int merge(int l1,int r1,int l2,int r2){
static int A[S+5] , B[S+5] , len1 , len2;
len1 = len2 = 0;
for(int i=sbl[bl[r1]];i<=r1;i++) if(sa[i]>=l1) A[len1++]=sa[i];
for(int i=l2;i<=ebl[bl[l2]];i++) if(sa[i]<=r2) B[len2++]=sa[i];
int i=0,j=0,ret=0;
for(;i<len1 && j<len2;)
if(a[A[i]] <= a[B[j]]) i++;
else ret+=len1-i , j++;
return ret;
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]),sb[++sb[0]]=a[i];
sort(sb+1,sb+1+sb[0]);
sb[0] = unique(sb+1,sb+1+sb[0])-sb-1;
for(int i=0;i<n;i++) a[i]=lower_bound(sb+1,sb+1+sb[0],a[i])-sb,bl[i]=i/S,sa[i]=i;
int m = bl[n-1];
for(int i=0;i<=m;i++){
memset(cnt1,0,sizeof cnt1);
int st = i * S , ed = min(n-1,st + S - 1);
for(int j=st;j<=ed;j++) cnt1[a[j]]++;
for(int j=1;j<=sb[0];j++) cnt1[j]+=cnt1[j-1];
for(int j=st-1;j>=0;j--) ans2[i][j] = ans2[i][j+1] + cnt1[a[j]-1];
for(int j=sb[0];j>=1;j--) cnt1[j]=cnt1[j]-cnt1[j-1]+cnt1[j+1];
for(int j=ed+1;j<n;j++) ans2[i][j] = ans2[i][j-1] + cnt1[a[j]+1];
memset(cnt2,0,sizeof cnt2);
for(int j=0;j+st<=ed;j++)
for(int k=0;k<j;k++)
cnt2[j][k] = (k?cnt2[j][k-1]:0) + (a[j+st]<a[k+st]);
for(int k=0;k+st<=ed;k++)
for(int j=k;j+st<=ed;j++)
ans1[i][k][j] = (j?ans1[i][k][j-1]:0) + (j?cnt2[j][j-1]:0) - (k?cnt2[j][k-1]:0);
sort(sa+st,sa+ed+1,cmp);
sbl[i] = st , ebl[i] = ed;
}
int q,la=0;
scanf("%d",&q);
for(int u,v;q--;){
scanf("%d%d",&u,&v);
u^=la,v^=la;
u--,v--;
if(bl[u] == bl[v]) la = ans1[bl[u]][u-sbl[bl[u]]][v-sbl[bl[u]]];
else{
la = ans1[bl[u]][u-sbl[bl[u]]][ebl[bl[u]]-sbl[bl[u]]] + ans1[bl[v]][0][v-sbl[bl[v]]];
for(int i=bl[u]+1;i<=bl[v]-1;i++){
la += ans1[i][0][ebl[i]-sbl[i]]
+ ans2[i][u]
+ ans2[i][v] - ans2[i][ebl[bl[v]-1]];
}
la += merge(u,ebl[bl[u]],sbl[bl[v]],v);
}
printf("%d\n",la);
}
}