zoukankan      html  css  js  c++  java
  • Evanyou Blog 彩带

      题目传送门

    逆序对

    题目描述

    猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。

    输入输出格式

    输入格式:

     

    第一行,一个数n,表示序列中有n个数。

    第二行n个数,表示给定的序列。

     

    输出格式:

     

    给定序列中逆序对的数目。

     

    输入输出样例

    输入样例#1: 复制
    6
    5 4 2 6 3 1
    
    输出样例#1: 复制
    11

    说明

    对于50%的数据,n≤2500

    对于100%的数据,n≤40000。


      分析:

      用归并或者树状数组都可以轻易A掉,但是这里用权值线段树。可以算是一道权值线段树的模板题。用于理解权值线段树。

      Code:

      

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+7;
    int n,p[maxn];ll ans;
    struct Num{
        int id,val;
    }a[maxn];
    struct Seg{
        int l,r;ll val;
    }seg[maxn<<2];
    inline void pushup(int rt)
    {
        seg[rt].val=seg[rt<<1].val+seg[rt<<1|1].val;
    }
    inline void build(int l,int r,int rt)
    {
        seg[rt].l=l,seg[rt].r=r;
        if(l==r){seg[rt].val=0;return;}
        int mid=(l+r)>>1;
        build(l,mid,rt<<1);
        build(mid+1,r,rt<<1|1);
    }
    inline void update(int rt,int x)
    {
        if(seg[rt].l==seg[rt].r&&seg[rt].l==x){
            seg[rt].val++;return;}
        int mid=(seg[rt].l+seg[rt].r)>>1;
        if(x<=mid)update(rt<<1,x);
        if(x>mid)update(rt<<1|1,x);
        pushup(rt);
    }
    inline ll quary(int rt,int l,int r)
    {
        if(seg[rt].l>r||seg[rt].r<l)return 0;
        if(l<=seg[rt].l&&seg[rt].r<=r)
            return seg[rt].val;
        int mid=(seg[rt].l+seg[rt].r)>>1;int ret=0;
        if(l<=mid)ret+=quary(rt<<1,l,r);
        if(r>mid)ret+=quary(rt<<1|1,l,r);
        return ret;
    }
    bool cmp(Num x,Num y)
    {return x.val<y.val;}
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n;
        build(1,maxn,1);
        for(int i=1;i<=n;i++)
            cin>>a[i].val,a[i].id=i;
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++)
             p[a[i].id]=i;
        for(int i=1;i<=n;i++){
            ans+=quary(1,p[i]+1,maxn);
            update(1,p[i]);}
        cout<<ans<<"
    ";
        return 0;
    } 
  • 相关阅读:
    Spark监控官方文档学习笔记
    Maven打包排除某个资源或者目录
    源码中的哲学——通过构建者模式创建SparkSession
    CentOS7启动Tomcat报错:./startup.sh: Permission denied
    Centos7 安装 redis
    centos7 查找jdk 安装路径
    Activemq(centos7)开机自启动服务
    /var/run/redis_6379.pid exists, process is already running or crashed解决方案
    activeMQ 修改端口号
    CentOS7.5 通过wget下载文件到指定目录
  • 原文地址:https://www.cnblogs.com/cytus/p/9226758.html
Copyright © 2011-2022 走看看