n根号n解决在线无修区间逆序对问题
来源:互联网 发布:女间谍知乎 编辑:程序博客网 时间:2024/05/29 19:57
做法
带log的分块相信大家都会,今天我们来讲讲不带log。
首先先离散化,这样值域就变成n了。
我们以根号为阈值分块,然后我们记A->B的含义是将A和B两个序列拼接在一起有多少逆序对两个元素一个来自A另一个来自B。
首先考虑如何求A->B,可以发现A和B的内部顺序是没有关系的,因此如果我们把A和B排好序了,运用归并即可线性求得A->B。
现在我们先把每个块排序,然后预处理一个位置到块头的逆序对个数(树状数组解决),接下来对于块内询问[l,r]假设块头和块尾分别是u和v,那么。
ans([l,r])=ans([u,r])-ans([u,l-1])-[u,l-1]->[l,r]。
其中前缀ans已经预处理,剩下那个可以归并。
我们解决块间贡献可以枚举两个块然后归并,接下来设f[l,r]表示第l到r块的答案。
f[l,r]=f[l,r-1]+f[l+1,r]-f[l+1,r-1]+l->r。
因此可以预处理块间贡献。
散块间贡献可以归并得到。
现在解决散块与块间的贡献。
可以先预处理一个位置对一个块的贡献。
可以将元素按顺序插入,维护一个块内的答案,即可预处理。
散块一定是到块头或块尾的区间,再前缀和或后缀和即可。
#include<cstdio>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;const int maxn=50000+10,B=224;int f[B+10][B+10],num[B+10],g[maxn][B+10];int tree[maxn];int a[maxn],belong[maxn],b[maxn],c[maxn],d[maxn],sum[maxn],cnt[maxn];int i,j,k,l,r,s,t,n,m,tot,top,ans,now;int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x*f;}bool cmp(int x,int y){ return a[x]<a[y];}int lowbit(int x){ return x&-x;}void change(int x){ while (x>0){ tree[x]++; x-=lowbit(x); }}int query(int x){ int t=0; while (x<=n){ t+=tree[x]; x+=lowbit(x); } return t;}int work(int top,int tot){ int i=1,j=1,t=0; while (i<=top&&j<=tot){ if (c[i]<=d[j]) i++; else{ j++; t+=top-i+1; } } return t;}int ask(int x,int l,int r){ int i,t=sum[r]-(l==(x-1)*B+1?0:sum[l-1]); top=0; fo(i,(x-1)*B+1,min(x*B,n)) if (b[i]<l) c[++top]=a[b[i]]; tot=0; fo(i,(x-1)*B+1,min(x*B,n)) if (b[i]>=l&&b[i]<=r) d[++tot]=a[b[i]]; t-=work(top,tot); return t;}int main(){ n=read(); fo(i,1,n) a[i]=read(),b[i]=a[i]; sort(b+1,b+n+1); top=unique(b+1,b+n+1)-b-1; fo(i,1,n) a[i]=lower_bound(b+1,b+top+1,a[i])-b; fo(i,1,n) belong[i]=(i-1)/B+1; fo(i,1,n) b[i]=i; sort(b+1,b+n+1,cmp); i=1; while (i<=n){ t=a[b[i]]; j=i; while (i<=n&&a[b[i]]==t){ fo(k,belong[b[i]]+1,belong[n]) g[b[i]][k]=num[k]; i++; } fo(k,j,i-1) num[belong[b[k]]]++; } fo(i,1,belong[n]) num[i]=0; reverse(b+1,b+n+1); i=1; while (i<=n){ t=a[b[i]]; j=i; while (i<=n&&a[b[i]]==t){ fo(k,1,belong[b[i]]-1) g[b[i]][k]=num[k]; i++; } fo(k,j,i-1) num[belong[b[k]]]++; } fo(j,1,belong[n]) fd(i,(j-1)*B,1) if (i%B!=0) g[i][j]+=g[i+1][j]; fo(j,1,belong[n]) fo(i,j*B+1,n) if (i%B!=1) g[i][j]+=g[i-1][j]; fo(i,1,n){ fo(j,1,belong[n]) g[i][j]+=g[i][j-1]; } fo(j,1,belong[n]){ fo(i,0,n) tree[i]=0; l=0; fo(i,(j-1)*B+1,min(j*B,n)){ l+=query(a[i]+1); sum[i]=l; change(a[i]); } fo(i,0,n) tree[i]=0; l=0; fd(i,min(j*B,n),(j-1)*B+1){ l+=query(n-a[i]+2); cnt[i]=l; change(n-a[i]+1); } } fo(i,1,n) b[i]=i; fo(i,1,belong[n]){ l=(i-1)*B+1;r=min(i*B,n); sort(b+l,b+r+1,cmp); } fo(i,1,belong[n]) f[i][i]=sum[min(i*B,n)]; fo(i,1,belong[n]-1) fo(j,i+1,belong[n]){ top=0; fo(k,(i-1)*B+1,i*B) c[++top]=a[b[k]]; tot=0; fo(k,(j-1)*B+1,min(j*B,n)) d[++tot]=a[b[k]]; f[i][j]=work(top,tot); } fd(i,belong[n]-1,1) fo(j,i+1,belong[n]) f[i][j]+=f[i][j-1]+f[i+1][j]-f[i+1][j-1]; m=read(); while (m--){ j=read();k=read(); j^=ans;k^=ans; l=belong[j];r=belong[k]; if (l==r){ ans=ask(l,j,k); printf("%d\n",ans); continue; } ans=f[l+1][r-1]; /*ans+=ask(l,j,l*B); ans+=ask(r,(r-1)*B+1,k);*/ ans+=cnt[j]; ans+=sum[k]; top=0; fo(i,(l-1)*B+1,l*B) if (b[i]>=j) c[++top]=a[b[i]]; tot=0; fo(i,(r-1)*B+1,min(r*B,n)) if (b[i]<=k) d[++tot]=a[b[i]]; ans+=work(top,tot); /*fo(i,l+1,r-1) ans+=g[j][i]; fo(i,l+1,r-1) ans+=g[k][i];*/ ans+=g[j][r-1]-g[j][l]; ans+=g[k][r-1]-g[k][l]; printf("%d\n",ans); }}
阅读全文
0 0
- n根号n解决在线无修区间逆序对问题
- 根号n分治排序
- 逆序对计算(NLOG(N))
- [逆序对] poj 2893 M × N Puzzle
- 解决n+1问题
- 解决IBatis中的多对一映射n+1问题
- 解决IBatis中的多对一映射n+1问题
- hdu4677 Query on Graph 根号n
- N皇后问题的解决
- 1+N问题及解决
- Hibernate 解决n+1问题
- DFS解决n皇后问题
- n皇后问题(C++解决)
- Hibernate解决n+1问题
- Java解决N皇后问题
- 合并排序法求n个数的逆序对
- hdu5273 n次查询求逆序数对
- POJ 2893 M × N Puzzle(逆序对-BIT)
- VUE2.0 的那些事(一)
- LeetCode-40-Combination Sum II ,同39
- 数字媒体显示和压缩(色彩二次抽样)
- fedora26命令yum、dnf不能使用
- Java中的异常捕获
- n根号n解决在线无修区间逆序对问题
- jq/js判断图片是否加载完毕
- bzoj1951 [Sdoi2010]古代猪文(Lucas+CRT+exgcd)
- Tensorflow滑动平均模型tf.train.ExponentialMovingAverage解析
- PL/SQL
- 技术简历的要与不要
- go语言学习笔记
- Composer 命令整理
- web项目中添加图标(unicode引用方式)