zoukankan      html  css  js  c++  java
  • 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]);
        }
    }

  • 相关阅读:
    桟错误分析方法
    gstreamer调试命令
    sqlite的事务和锁,很透彻的讲解 【转】
    严重: Exception starting filter struts2 java.lang.NullPointerException (转载)
    eclipse 快捷键
    POJ 1099 Square Ice
    HDU 1013 Digital Roots
    HDU 1087 Super Jumping! Jumping! Jumping!(动态规划)
    HDU 1159 Common Subsequence
    HDU 1069 Monkey and Banana(动态规划)
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/8312594.html
Copyright © 2011-2022 走看看