前言

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

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

显然我们有

\(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. Confluence 6 选项 2 – 转移 Crowd/Jira 应用程序中的用户和用户组到 Confluence 数据库

    当你打算合并的外部目录服务器(Crowd 或 Jira 应用)有大量的用户到 Confluence 数据库中的时候,请使用这个选项.你需要有基本的 SQL 知识才能完成这个任务. 下面的 SQL 命令 ...

  2. python-day41--数据库---数据类型

    一.存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 二.mysql 数据类型 1.数字:(宽度指的是显示宽度,与存储无关)     不用指定宽度, ...

  3. python-day8-循环补充

    # msg='hello'# msg=[1,2,3,4,5,6]# msg=(1,2,3,4,5,6) # index=0# while index < len(msg):# print(msg ...

  4. WaitForMultipleObjects用法详解

    本文转载于:http://blog.csdn.net/sac761/article/details/52456385 WaitForMultipleObjects是Windows中的一个功能非常强大的 ...

  5. nyoj1248(阅读理解???)

    海岛争霸 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比海盗,你知道吧?杰克船长驾驶着自己 ...

  6. 高精度减法用string 和 stack

    #include "bits/stdc++.h" using namespace std; int main() { string a,b; while(cin >> ...

  7. 【转】json与jsonp区别浅析(json才是目的,jsonp只是手段)

    一言以蔽之,json返回的是一串数据:而jsonp返回的是脚本代码(包含一个函数调用): JSON其实就是JavaScript中的一个对象,跟var obj={}在质上完全一样,只是在量上可以无限扩展 ...

  8. Idea热部署jrebel失败

    Idea热部署jrebel

  9. Ybquery项目部署idea

    家庭公计网的引用  

  10. ajax缓存和编码问题

    ajax缓存问题,工作中几乎使用ajax都会碰到,虽然解决缓存问题很多,但我 一直使用常用的,方便理解的,没有多大记忆成本的,get方式的缓存问题很蛋疼,尤其是低版本IE啦,废话少说, <scr ...