zoukankan      html  css  js  c++  java
  • bzoj3295 洛谷P3157、1393 动态逆序对——树套树

    题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295

    洛谷 P3157(同一道题) https://www.luogu.org/problemnew/show/P3157

    洛谷 P1393(略有不同) https://www.luogu.org/problemnew/show/P1393

    动态逆序对问题;

    树状数组套权值线段树,动态开点;

    就像树状数组那样做就可以了,每个线段树维护一段区间内的不同权值的数的个数;

    删除一个点,就把答案减去它贡献的逆序对数量就可以了;

    有点不太懂空间范围怎么算...

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int const maxn=1e5+5,maxm=maxn*100;
    int n,m,pos[maxn],t[maxn],rt[maxn],ls[maxm],rs[maxm],sum[maxm],cnt;
    ll ans;
    ll getsum(int x)
    {
        ll ret=0;
        for(;x;x-=(x&-x)) ret+=t[x]; 
        return ret;
    }
    void add(int x)
    {
        for(;x<=n;x+=(x&-x)) t[x]++;
    }
    void update(int &x,int l,int r,int p,int v)
    {
        if(!x)x=++cnt; sum[x]+=v;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(p<=mid)update(ls[x],l,mid,p,v);
        else update(rs[x],mid+1,r,p,v);
    }
    void insert(int x,int p,int v)
    {
        for(;x<=n;x+=(x&-x)) update(rt[x],1,n,p,v);
    }
    ll ask(int x,int l,int r,int p)
    {
        if(l==r)return sum[x];
        int mid=(l+r)>>1;
        if(p<=mid)return ask(ls[x],l,mid,p);
        return sum[ls[x]]+ask(rs[x],mid+1,r,p);
    }
    ll query(int x,int p)//<=p 的个数 
    {
        ll ret=0;
        for(;x;x-=(x&-x)) ret+=ask(rt[x],1,n,p);
        return ret;
    }
    ll pre(int x,int p){return query(p,n)-query(p,x);}
    ll suf(int x,int p){return query(n,x)-query(p,x);}
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x;i<=n;i++)
        {
            scanf("%d",&x); pos[x]=i;
            ans+=getsum(n)-getsum(x);
            add(x); insert(i,x,1);
        }
        for(int i=1,x;i<=m;i++)
        {
            printf("%lld
    ",ans); scanf("%d",&x);
            ans-=pre(x,pos[x])+suf(x,pos[x]);
            insert(pos[x],x,-1);
        }
        return 0;
    }

    洛谷P1393,离散化一下即可。(通过数喜+1)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int const maxn=4e4+5,maxm=maxn*100;
    int n,m,t[maxn],rt[maxn],ls[maxm],rs[maxm],sum[maxm],cnt,tot;
    ll ans,a[maxn],b[maxn];
    ll getsum(int x)
    {
        ll ret=0;
        for(;x;x-=(x&-x)) ret+=t[x]; 
        return ret;
    }
    void add(int x)
    {
        for(;x<=n;x+=(x&-x)) t[x]++;
    }
    void update(int &x,int l,int r,int p,int v)
    {
        if(!x)x=++cnt; sum[x]+=v;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(p<=mid)update(ls[x],l,mid,p,v);
        else update(rs[x],mid+1,r,p,v);
    }
    void insert(int x,int p,int v)
    {
        for(;x<=n;x+=(x&-x)) update(rt[x],1,n,p,v);
    }
    ll ask(int x,int l,int r,int p)
    {
        if(l==r)return sum[x];
        int mid=(l+r)>>1;
        if(p<=mid)return ask(ls[x],l,mid,p);
        return sum[ls[x]]+ask(rs[x],mid+1,r,p);
    }
    ll query(int x,int p)//<=p 的个数 
    {
        ll ret=0;
        for(;x;x-=(x&-x)) ret+=ask(rt[x],1,n,p);
        return ret;
    }
    ll pre(int x,int p){return query(p,n)-query(p,x);}
    ll suf(int x,int p){return query(n,x)-query(p,x);}
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1); 
        tot=unique(b+1,b+n+1)-b-1;
        for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
        for(int i=1;i<=n;i++)
        {
            ans+=getsum(n)-getsum(a[i]);
            add(a[i]); insert(i,a[i],1);
        }
        for(int i=1,k;i<=m;i++)
        {
            printf("%lld ",ans); scanf("%d",&k);
            ans-=pre(a[k],k)+suf(a[k],k);
            insert(k,a[k],-1);
        }
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    数据库学习笔记3--基本的SQL语句
    数据库学习笔记2--MySQL数据类型
    数据库学习笔记1----MySQL 5.6.21的安装和配置(setup版)
    JavaWeb学习笔记1---http协议
    Spring学习笔记18--通过工厂方法配置Bean
    Spring学习笔记17--在XML中使用SPEL
    Spring 学习笔记16---properties文件的两种方式
    Spring学习笔记15--注解Bean
    Spring4.0学习笔记1---开发环境搭建
    Installed JREs时 Standard 1.1.x VM与Standard VM的区别
  • 原文地址:https://www.cnblogs.com/Zinn/p/9226522.html
Copyright © 2011-2022 走看看