zoukankan      html  css  js  c++  java
  • bzoj3289: Mato的文件管理

    传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3289

    思路:比较裸的莫队。

    交换次数显然是逆序对个数...

    然后考虑怎么从[l,r]的逆序对个数得到[l,r+1]的逆序对个数。

    先离散化,用树状数组维护权值,我们只要考虑对于新加进来的这个数,原区间中有多少个数大于它,拿区间长度去减就可以得到这个数的贡献。

    删除一个数类似。

    复杂度O(n^1.5*logn)

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    const int maxn=50010;
    using namespace std;
    struct data{int id,rank;}file[maxn];
    struct que{int l,r,id;}q[maxn];
    int n,m,sz,a[maxn],bel[maxn],ans[maxn],cnt,res,T[maxn];
    bool cmp(data a,data b){return a.rank<b.rank;}
    bool cmp2(que a,que b){return bel[a.l]==bel[b.l]?a.r<b.r:bel[a.l]<bel[b.l];}
    void modify(int x,int add){for (;x<=n;x+=x&(-x)) T[x]+=add;}
    int query(int x){int res=0;for (;x;x-=x&(-x)) res+=T[x];return res;}
    
    void work(){
    	for (int i=1,l=1,r=0;i<=m;i++){
    		for (;r<q[i].r;r++) res+=(r-l+1-query(a[r+1])),modify(a[r+1],1);
    		for (;r>q[i].r;r--) res-=(r-l+1-query(a[r])),modify(a[r],-1);
    		for (;l<q[i].l;l++) res-=query(a[l]-1),modify(a[l],-1);
    		for (;l>q[i].l;l--) res+=query(a[l-1]-1),modify(a[l-1],1);
    		ans[q[i].id]=res;
    	}
    	for (int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    }
    
    int main(){
    	scanf("%d",&n);sz=sqrt(n);
    	for (int i=1;i<=n;i++) bel[i]=(i-1)/sz+1;
    	for (int i=1;i<=n;i++) scanf("%d",&file[i].rank),file[i].id=i;
    	sort(file+1,file+1+n,cmp);
    	for (int i=1;i<=n;i++){if (file[i].rank!=file[i-1].rank) ++cnt;a[file[i].id]=cnt;}
    	scanf("%d",&m);
    	for (int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
    	sort(q+1,q+1+m,cmp2),work();
    	return 0;
    }


  • 相关阅读:
    Linux終端一行命令发送邮件
    团队冲刺2.4
    团队冲刺2.3
    团队冲刺2.2
    找水王
    评价win10自带输入法——微软拼音输入法
    梦断代码阅读笔记01
    团队冲刺2.1
    第十三周总结
    第十二周总结
  • 原文地址:https://www.cnblogs.com/thythy/p/5493541.html
Copyright © 2011-2022 走看看