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]);
        }
    }

  • 相关阅读:
    python接口测试
    python selenium 判断元素是否可见
    python学习之天气爬虫
    python学习之图片爬虫
    python学习之小说爬虫
    webdriver学习——css调试,jquery调用
    webdriver学习——百度设置
    bat中获取当前路径
    搭建ant脚本,全量/增量/减量包
    查询数据库中各个类型的方法名称
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477169.html
Copyright © 2011-2022 走看看