• Jzoj1020 逆序对统计 ≈ Bzoj3295 动态逆序对


    Jzoj1020:

    Dramatic是在太菜了。最近,他学习了有关逆序对的知识,并且掌握了计算一个序列逆序对个数的高效算法,因此,他兴冲冲的跑去向YY牛炫耀。YY牛对此不屑一顾,并打击Dramatic说:“这是在太小儿科了!”Dramatic很不甘心,于是在他的强烈要求下,YY牛给他出了一道跟逆序对有关的“难题”(显然,对于YY牛来说是简单题)。题目是这样的:YY牛首先给Dramatic一个长度为N的整数序列A。接下来,YY牛会对Dramatic说:把A的第i个数字改成j,同时告诉我现在A中逆序对的个数。重复了若干次之后,Dramatic已经算得头晕眼花,支撑不住了。然而,YY牛的命令一共有M个!为了解决这个问题,Dramatic只好你,你能够帮助Dramatic解决YY牛的“难题”吗?

    两道题目差不多,这里一起讲

    因为先做了上面那道,所以直接没考虑cdq写了BIT套主席树,结果被卡空间,乱搞了一下才过,不过特别好写是真的

    #pragma GCC opitmize("O3")
    #pragma G++ opitmize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define mid (l+r>>1)
    using namespace std;
    struct tree{ int l,r,s; } s[10000010];
    int rt[100010],v[100010],n,m,cnt=0,ans=0;
    inline void insert(int l,int r,int& x,int k){
    	if(!x) x=++cnt; ++s[x].s;
    	if(l==r) return;
    	if(k<=mid) insert(l,mid,s[x].l,k);
    		else insert(mid+1,r,s[x].r,k);
    }
    inline void remove(int l,int r,int& x,int k){
    	--s[x].s;
    	if(l==r) return;
    	if(k<=mid) remove(l,mid,s[x].l,k);
    		else remove(mid+1,r,s[x].r,k);
    }
    inline int gMin(int l,int r,int x,int k){
    	if(l==r) return 0;
    	if(k<=mid) return gMin(l,mid,s[x].l,k);
    	return s[s[x].l].s+gMin(mid+1,r,s[x].r,k);
    }
    inline int gMax(int l,int r,int x,int k){
    	if(l==r) return 0;
    	if(k>mid) return gMax(mid+1,r,s[x].r,k);
    	return s[s[x].r].s+gMax(l,mid,s[x].l,k);
    }
    int cal(int v,int p){
    	int ans=0;
    	for(int x=p;x;x&=x-1) ans+=gMax(1,50000,rt[x],v);
    	for(int x=n;x;x&=x-1) ans+=gMin(1,50000,rt[x],v);
    	for(int x=p;x;x&=x-1) ans-=gMin(1,50000,rt[x],v);
    	return ans;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		scanf("%d",v+i);
    		for(int j=i;j<=n;j+=j&-j) 
    			insert(1,50000,rt[j],v[i]);
    	}
    	for(int i=1;i<=n;++i) 
    		ans+=cal(v[i],i);
    	scanf("%d",&m); ans>>=1;
    	for(int x,y;m--;){
    		scanf("%d%d",&x,&y);
    		ans-=cal(v[x],x);
    		for(int j=x;j<=n;j+=j&-j){
    			remove(1,50000,rt[j],v[x]);
    			insert(1,50000,rt[j],y);
    		}
    		ans+=cal(v[x]=y,x);
    		printf("%d
    ",ans);
    	}
    }
    于是顺便切掉了bzoj3295,直接用上一题板子,简直比cdq短(man)太多

    #pragma GCC opitmize("O3")
    #pragma G++ opitmize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define mid (l+r>>1)
    using namespace std;
    struct tree{ int l,r,s; } s[10000010];
    int rt[250010],v[250010],n,m,cnt=0,p[100010]; long long ans=0;
    inline void insert(int l,int r,int& x,int k){
        if(!x) x=++cnt; ++s[x].s;
        if(l==r) return;
        if(k<=mid) insert(l,mid,s[x].l,k);
            else insert(mid+1,r,s[x].r,k);
    }
    inline void remove(int l,int r,int& x,int k){
        --s[x].s;
        if(l==r) return;
        if(k<=mid) remove(l,mid,s[x].l,k);
            else remove(mid+1,r,s[x].r,k);
    }
    inline int gMin(int l,int r,int x,int k){
        if(l==r) return 0;
        if(k<=mid) return gMin(l,mid,s[x].l,k);
        return s[s[x].l].s+gMin(mid+1,r,s[x].r,k);
    }
    inline int gMax(int l,int r,int x,int k){
        if(l==r) return 0;
        if(k>mid) return gMax(mid+1,r,s[x].r,k);
        return s[s[x].r].s+gMax(l,mid,s[x].l,k);
    }
    int cal(int v,int p){
        int ans=0;
        for(int x=p;x;x&=x-1) ans+=gMax(1,n,rt[x],v);
        for(int x=n;x;x&=x-1) ans+=gMin(1,n,rt[x],v);
        for(int x=p;x;x&=x-1) ans-=gMin(1,n,rt[x],v);
        return ans;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i){
            scanf("%d",v+i); p[v[i]]=i;
            for(int j=i;j<=n;j+=j&-j) 
                insert(1,n,rt[j],v[i]);
        }
        for(int i=1;i<=n;++i) ans+=cal(v[i],i);
        ans>>=1;
        for(int x,y;m--;){
            printf("%lld
    ",ans);
            scanf("%d",&x); x=p[x];
            ans-=cal(v[x],x);
            for(int j=x;j<=n;j+=j&-j)
                remove(1,n,rt[j],v[x]);
        }
    }

  • 相关阅读:
    基于Windows环境下Myeclipse10.0下载安装破解及jdk的下载安装及环境变量的配置
    51 Nod 1791 合法括号子段【分治+字符串】
    一步一步深入理解Dijkstra算法
    POJ 3662 Telephone Lines【Dijkstra最短路+二分求解】
    拍拍网接入微信卡包备战双12圣诞购物季
    公众平台认证订阅号接口调整 增加群发接口等,可授权登录
    搜狗搜索推广品牌专区新增微信互动区展示企业微信公众号内容
    WP8版微信5.4发布 新增夜间模式 暂没小视频
    Kik CEO Ted Livingston发博称要成为西方的微信?
    微信"附近的人"新增商家公众号入驻功能
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/8312594.html
Copyright © 2020-2023  润新知