zoukankan      html  css  js  c++  java
  • 树状数组复习+模板整理(8.1号更新)

    资料:

    求逆序对:https://blog.csdn.net/ssimple_y/article/details/53744096

    离散化:https://blog.csdn.net/xiangaccepted/article/details/73276826

    一、离散化+求逆序对数

    //a[i] = 5, 将5插进数组,然后求5和5前面出现的数x,本来5是第i个出现,前面出现了x-1个比5小的,所以i-1-(x-1)就是前面出现的比5大的数,就是逆序对数。
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 5e5+10;
    const double eps = 1e-8;
    const double pi = acos(-1.0);
    int a[maxn],t[maxn],c[maxn];
    int n;
    
    
    int getsum(int x)
    {
        int sum = 0;
        while(x>0)
        {
            sum += c[x];
            x -= x&(-x);
        }
        return sum;
    }
    
    void add(int x,int k)
    {
        while(x<=n)
        {
            c[x] += k;
            x += x&(-x);
        }
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF&&n)
        {
    
            for(int i=1;i<=n;i++)
            {
                c[i] = 0;
                scanf("%d",&a[i]);
                t[i] = a[i];
            }
    
            sort(t+1,t+n+1);
            int m = unique(t+1,t+1+n)-t-1;
            for(int i=1;i<=n;i++)
            {
                a[i] = lower_bound(t+1,t+1+m,a[i])-t;
            }
    
            ll ans = 0;
            for(int i=1;i<=n;i++)
            {
                add(a[i],1);
                ans += (ll)i-getsum(a[i]);
                            //i第i个位置,getsum(a[i])=a[i]前出现的数
                            //a[i] = 5, 将5插进数组,然后求5和5前面出现的数x,本来5是第i个出现,前面出现了x-1个比5小的,所以i-1-(x-1)就是前面出现的比5大的数,就是逆序对数。
            }
            printf("%lld
    ",ans);
        }
    }    
    View Code

    正反求两次逆序对(对于第i项,求前面比i小的和前面比i大的,求后面比i小的和后面比i大的)

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define lowbit(x) x&(-x)
    
    #define readint(x) scanf("%d",&x);
    #define readll(x) scanf("%lld",&x);
    #define readdb(x) scanf("%lf",&x);
    #define reads(x) scanf("%s",x);
    #define rep(i,l,r) for(int i=l;i<=r;++i)
    #define per(i,r,l) for(int i=r;i>=l;--i)
    
    using namespace std;
    typedef long long ll;
    const int maxn = 3e5+10;
    const double eps = 1e-8;
    const double pi = acos(-1.0);
    ll a[maxn],c[maxn];
    int n;
    
    
    ll getsum(ll x)
    {
        ll sum = 0;
        while(x>0)
        {
            sum += c[x];
            x -= lowbit(x);
        }
        return sum;
    }
    
    void add(ll x,ll k)
    {
        while(x<maxn)
        {
            c[x] += k;
            x += lowbit(x);
        }
    }
    
    ll nxt_big[maxn],nxt_small[maxn],pre_big[maxn],pre_small[maxn];
    
    int main()
    {
        int T;
        readint(T);
        while(T--)
        {
            int n;
            readint(n);
            int x,y;
            memset(pre_small,0,sizeof(pre_small));
            memset(pre_big,0,sizeof(pre_big));
            memset(nxt_small,0,sizeof(nxt_small));
            memset(nxt_big,0,sizeof(nxt_big));
            memset(c,0,sizeof(c));
            memset(a,0,sizeof(a));
            rep(i,1,n)
            {
                readll(a[i]);
                pre_small[i] = getsum(a[i]);
                add(a[i],1);
                pre_big[i] = i-pre_small[i]-1;
            }
            memset(c,0,sizeof(c));
            per(i,n,1)
            {
                nxt_small[i] = getsum(a[i]);
                add(a[i],1);
                nxt_big[i] = n-i-nxt_small[i];
            }
            ll ans = 0;
            rep(i,1,n)
            {
                ans += pre_small[i]*nxt_big[i];
                ans += pre_big[i]*nxt_small[i];
            }
            printf("%lld
    ",ans);
        }
    }
    View Code
  • 相关阅读:
    rocketMQ
    RocketMQ 事务消息
    Serial,Parallel,CMS,G1四大GC收集器特点小结
    CMS垃圾收集器与G1收集器
    CMS垃圾回收过程
    MySQL中EXPLAIN解释命令 查看索引是否生效
    redis持久化的几种方式
    深入浅出数据库索引原理
    Java中堆内存和栈内存详解
    jvm垃圾回收机制
  • 原文地址:https://www.cnblogs.com/WWkkk/p/9400074.html
Copyright © 2011-2022 走看看