前言

看了大家的做法,什么冒泡排序,插入排序,树状数组,线段树,都好厉害呐,我都没想出来

但我发现竟然还没有人用主席树,于是我跟大家交流一下 主席树 做法

显然我们有

\(Ans=\sum_{i=1}^n\sum_{j=1}^{i-1}a_j\geq{}a_i\)

于是这样用主席树做

考虑每个\(i\)对\(Ans\)的贡献,发现只需要统计出大于\(a_i\)的数的个数,注意这些数应该是已经出现了的

用主席树维护答案,查询\(0\to{}i-1\)的历史版本,做法已经很明确了

最后分析时间复杂度

对每个\(i\)我们要先查询\([a_i+1,n]\)数的个数,需要\(O(\log_2n)\)时间,然后插入这个数也需要\(O(\log_2n)\)时间

因此总时间复杂度为\(O(n\log_2n)\)

放代码

#include<iostream>
#include<cstring>
using namespace std;

const int maxn=1e4+7;
struct PreSegTree
{
    int sum;
    int L,R;
}PST[maxn*16];
int root[maxn],cnt;

void insert(int&now,int l,int r,int x)
{
    PST[++cnt]=PST[now];
    now=cnt;
    ++PST[now].sum;
    if(l==r) return;
    int mid=(l+r)>>1;
    if(x<=mid)
        insert(PST[now].L,l,mid,x);
    else if(x>=mid+1)
        insert(PST[now].R,mid+1,r,x);
}

int query(int i,int j,int l,int r,int ql,int qr)
{
    if(ql<=l&&r<=qr)
        return PST[j].sum-PST[i].sum;
    int mid=(l+r)>>1;
    int ans=0;
    if(ql<=mid)
        ans+=query(PST[i].L,PST[j].L,l,mid,ql,qr);
    if(qr>=mid+1)
        ans+=query(PST[i].R,PST[j].R,mid+1,r,ql,qr);
    return ans;
}

int main()
{
    memset(PST,0,sizeof(PST));
    memset(root,0,sizeof(root));
    cnt=0;
    int n;
    cin>>n;
    int a,ans=0;
    for(int i=1;i<=n;++i)
    {
        cin>>a;
        if(a<n) // 注意a==n时统计要特判掉
            ans+=query(root[0],root[i-1],1,n,a+1,n);
        root[i]=root[i-1];
        insert(root[i],1,n,a);
    }
    cout<<ans<<endl;
}

LG1116 【车厢重组】的更多相关文章

  1. codevs 1683 车厢重组

    1683 车厢重组  时间限制: 1 s  空间限制: 1000 KB  题目等级 : 白银 Silver   题目描述 Description 在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥 ...

  2. codevs 1683 车厢重组(水题日常)

    时间限制: 1 s  空间限制: 1000 KB  题目等级 : 白银 Silver 题目描述 Description 在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转.一个车站的职工 ...

  3. P1116 车厢重组

    题目描述 在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转.一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车 ...

  4. T1683 车厢重组 codevs

    http://codevs.cn/problem/1683/  时间限制: 1 s  空间限制: 1000 KB  题目等级 : 白银 Silver 题目描述 Description 在一个旧式的火车 ...

  5. P1058 车厢重组

    题目描述 在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转.一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转 \(180\) 度,则可以把相邻两节车厢的位置交换,用这种方法可 ...

  6. (Java实现) 车厢重组

    [问题描述] 在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转.一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排 ...

  7. Zerojudge解题经验交流

    题号:a001: 哈囉 背景知识:输出语句,while not eof 题号:a002: 簡易加法 背景知识:输出语句,while not eof,加法运算 题号:a003: 兩光法師占卜術 背景知识 ...

  8. 暑假集训(1)第五弹 -----Rails(Uva514)

    PopPush城市有一座著名的火车站.这个国家到处都是丘陵.而这个火车站是建于上一个世纪.不幸的是,那时的资金有限.所以只能建立起一条路面铁轨.而且,这导致这个火车站在同一个时刻只能一个轨道投入使用, ...

  9. UVA514 Rails

     铁轨 PopPush城市有一座著名的火车站.这个国家到处都是丘陵.而这个火车站是建于上一个世纪.不幸的是,那时的资金有限.所以只能建立起一条路面铁轨.而且,这导致这个火车站在同一个时刻只能一个轨道投 ...

随机推荐

  1. hdu-4289 最大流Dinic模板题

    拆点,套模板. 详情见代码. // // main.cpp // hdu_4289 // // Created by Luke on 16/8/29. // Copyright © 2016年 Luk ...

  2. service几种访问类型(集群外负载均衡访问LoadBalancer , 集群内访问ClusterIP,VPC内网负载均衡LoadBalancer ,集群外访问NodePort)

    一.集群外访问(负载均衡) kind: ServiceapiVersion: v1spec: ports: - protocol: TCP port: 4341 targetPort: 8080 no ...

  3. git上传文件到github与gulp的简单使用

    git有两种方式提交源代码到github 第一种方式通过地址提交下面介绍的是通过ssh方式上传 git使用ssh方式上传代码到githubgit首先要生成公钥和私钥 将公钥添加到github中将私钥保 ...

  4. ASP.NET MVC 习惯

  5. 组播IP地址

    组播IP地址组播IP地址用于标识一个IP组播组.IANA(internet assigned number authority)把D类地址空间分配给IP组播,其范围是从224.0.0.0到239.25 ...

  6. C语言-简单选择排序与直接插入排序的实现

    /* Name: selectSort and insertSort Copyright: nyist Author: 润青 Date: 01/10/18 19:30 Description: 实现了 ...

  7. Openwrt Export Gpio Configure (7)

    1      Scope of Document This document describes how to export gpio interface under gpio-export driv ...

  8. bzoj1081

    题解: 先暴力找规律 然后就一加一减的枚举 代码: #include<bits/stdc++.h> using namespace std; ],p[]; int main() { sca ...

  9. <NET CLR via c# 第4版> 读书笔记--目录

    <NET CLR via c# 第4版>个别章节虽读过多次,但始终没有完整读过这本书.即使看过的那些,时间一长,也忘记了大部分.趁着最近不忙,想把这本书好好读一遍,顺便记下笔记,方便随时查 ...

  10. anu - reactIE

    import { options } from "./util"; import { Children } from "./Children"; import ...