[bzoj3744]Gty的妹子序列【分块】【主席树】
2018-03-16 20:56
330 查看
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=3744
【题解】
分块套路题。
首先可以用可持久化线段树在O(logN)O(logN)的时间内求出,一个点在一段区间内的逆序对数。
其次可以在O(T)O(T)的时间内求出两个大小为TT的有序区间的相互的逆序对数(Two pointers)。
那么就可以分块了,预处理处理出一个与块一段紧邻着它的块的逆序对数,O(N3/2)O(N3/2),查询时两边暴力查询,中间统一计算。总复杂度:O(NN−−√logN+N3/2)O(NNlogN+N3/2),显然这个复杂度不够平均,把块在设小一点可以获得更优的复杂度。
http://www.lydsy.com/JudgeOnline/problem.php?id=3744
【题解】
分块套路题。
首先可以用可持久化线段树在O(logN)O(logN)的时间内求出,一个点在一段区间内的逆序对数。
其次可以在O(T)O(T)的时间内求出两个大小为TT的有序区间的相互的逆序对数(Two pointers)。
那么就可以分块了,预处理处理出一个与块一段紧邻着它的块的逆序对数,O(N3/2)O(N3/2),查询时两边暴力查询,中间统一计算。总复杂度:O(NN−−√logN+N3/2)O(NNlogN+N3/2),显然这个复杂度不够平均,把块在设小一点可以获得更优的复杂度。
/* -------------- user Vanisher problem bzoj-3744 ----------------*/ # include <bits/stdc++.h> # define ll long long # define inf 0x3f3f3f3f # define N 50010 # define K 1010 # define L 1 # define R 2147483647 # define ui unsigned int using namespace std; ui read(){ ui tmp=0, fh=1; char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();} while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();} return tmp*fh; } struct node{ ui pl,pr,num; }T[N*40]; ui sum[K][K],k[K][K],num,size[K],place,n,a ,S,rt ,sl[K],sr[K],p ; void pre(){ for (int i=1; i<=num; i++) for (int j=sl[i]; j<sr[i]; j++) for (int t=j+1; t<=sr[i]; t++) if (a[j]>a[t]) sum[i][i]++; for (ui i=1; i<=num; i++) for (ui j=i+1; j<=num; j++){ sum[i][j]=sum[i][j-1]; for (ui pl=1, pr=1; pl<=size[i]; pl++){ while (pr<=size[j]&&k[j][pr]<k[i][pl]) pr++; sum[i][j]=sum[i][j]+pr-1; } } } ui extend(ui x, ui las, ui l, ui r){ ui now=++place; T[now].num=T[las].num+1; if (l==r) return now; ui mid=(l+r)/2; if (mid>=x){ T[now].pl=extend(x,T[las].pl,l,mid); T[now].pr=T[las].pr; } else { T[now].pl=T[las].pl; T[now].pr=extend(x,T[las].pr,mid+1,r); } return now; } ui querymx(ui x, ui nowr, ui nowl, ui l, ui f606 r){ if (l>x) return T[nowr].num-T[nowl].num; if (r<=x) return 0; ui mid=(l+r)/2; return querymx(x,T[nowr].pl,T[nowl].pl,l,mid)+querymx(x,T[nowr].pr,T[nowl].pr,mid+1,r); } ui querymn(ui x, ui nowr, ui nowl, ui l, ui r){ if (r<x) return T[nowr].num-T[nowl].num; if (l>=x) return 0; ui mid=(l+r)/2; return querymn(x,T[nowr].pl,T[nowl].pl,l,mid)+querymn(x,T[nowr].pr,T[nowl].pr,mid+1,r); } int main(){ n=read(); S=(int)pow(n,0.4)+1; for (ui i=1; i<=n; i++) a[i]=read(); for (ui i=1; i<=n; i++) rt[i]=extend(a[i],rt[i-1],L,R); sl[num=1]=1; ui now=0; for (ui i=1; i<=n; i++){ if (now==S){ size[num]=now; sr[num]=i-1; sort(k[num]+1,k[num]+size[num]+1); num++; now=0; sl[num]=i; } k[num][++now]=a[i]; p[i]=num; } size[num]=now; sr[num]=n; sort(k[num]+1,k[num]+size[num]+1); pre(); ui m=read(), lastans=0; for (ui i=1; i<=m; i++){ ui l=read()^lastans, r=read()^lastans; lastans=0; if (p[l]==p[r]){ for (ui j=l; j<r; j++) lastans+=querymn(a[j],rt[r],rt[j],L,R); } else { for (ui j=l; j<=sr[p[l]]; j++) lastans+=querymn(a[j],rt[r],rt[j],L,R); for (ui j=sl[p[r]]; j<=r; j++) lastans+=querymx(a[j],rt[j-1],rt[sr[p[l]]],L,R); for (ui j=p[l]+1; j<=p[r]-1; j++) lastans+=sum[j][p[r]-1]; } printf("%u\n",lastans); } return 0; }
相关文章推荐
- 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
- 【BZOJ3744】Gty的妹子序列-序列分块+树状数组
- 【BZOJ3744】Gty的妹子序列 分块+树状数组
- [BZOJ]3744: Gty的妹子序列 分块+树状数组+主席树
- 【分块】【树状数组】bzoj3744 Gty的妹子序列
- bzoj3744:Gty的妹子序列 (分块+树状数组)
- bzoj 3744: Gty的妹子序列 主席树+分块
- BZOJ 3809 Gty的二逼妹子序列 莫队算法+分块
- [bzoj3744]Gty的妹子序列
- 【BZOJ3809/3236】Gty的二逼妹子序列 [Ahoi2013]作业 莫队算法+分块
- BZOJ3787 gty的文艺妹子序列 【树状数组】【分块】
- BZOJ 3744 Gty的妹子序列 分块+树状数组+可持久化线段树
- BZOJ 3809: Gty的二逼妹子序列 莫队套分块
- [BZOJ3809]Gty的二逼妹子序列(莫队+分块)
- bzoj3744: Gty的妹子序列
- BZOJ 3809: Gty的二逼妹子序列(莫队+分块)
- [bzoj 3809] Gty的二逼妹子序列 莫队+分块
- BZOJ3744: Gty的妹子序列
- bzoj 3809: Gty的二逼妹子序列 分块+莫队算法
- Bzoj 3809: Gty的二逼妹子序列 莫队,分块