• [vijos1459][车展]


    题目链接

    思路

    首先可以证明当这个高度是中位数的时候耗费时间是最少了。所以可以(n^2log(n))用一个treap预处理出每个区间的中位数。
    然后就是知道了中位数怎么计算答案的问题。
    然后发现暴力n*m的扫能过而且跑的还不慢
    但是作为一个正直善良的OIER我还是用(n^2log(n))做的。
    发现用中位数减去比他小的在加上比中位数大的减去中位数,恰好可以把中位数给抵消掉(并不是都可以完全抵消掉,这个可以根据中位数的位置算一下),然后发现其实就是用那些比中位数大的数减去比中位数小(或者等于)的数,要不要再加回来一个中位数要特判一下。

    代码

    //寻找每个区间内的中位数
    /*
    * @Author: wxyww
    * @Date:   2018-12-02 10:36:55
    * @Last Modified time: 2018-12-02 14:22:15
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<bitset>
    #define ls TR[cur].ch[0]
    #define rs TR[cur].ch[1]
    using namespace std;
    typedef long long ll;
    const int N = 2010;
    ll read() {
       ll x = 0,f = 1;char c = getchar();
       while(c < '0' || c > '9') {
          if(c == '-') f = -1;
          c = getchar();
       }
       while(c >= '0' && c <= '9') {
          x = x * 10 + c - '0';
          c = getchar();
       }
       return x * f;
    }
    struct node {
       int ch[2],id,val,siz,cnt;
       ll VAL;
       void CLEAR() {
          ch[1] = ch[0] = id = val = siz = cnt = VAL = 0;
       }
    }TR[N];
    void up(int cur) {
       TR[cur].siz = TR[ls].siz + TR[rs].siz + TR[cur].cnt;
       TR[cur].VAL = TR[ls].VAL + TR[rs].VAL + TR[cur].val * TR[cur].cnt;
    }
    void rotate(int &cur,int f) {
       int son = TR[cur].ch[f];
       TR[cur].ch[f] = TR[son].ch[f ^ 1];
       TR[son].ch[f ^ 1] = cur;
       up(cur);cur = son;up(cur);
    }
    int tot;
    void insert(int &cur,int val) {
       if(!cur) {
          cur = ++tot;
          TR[cur].val = val;
          TR[cur].id = rand();
          TR[cur].siz = TR[cur].cnt = 1;
          TR[cur].VAL = val;
          TR[cur].ch[1] = TR[cur].ch[0] = 0;
          return;
       }
       if(val == TR[cur].val) {TR[cur].cnt++;TR[cur].siz++;TR[cur].VAL += val;return;}
       int d = val > TR[cur].val;
       insert(TR[cur].ch[d],val);
       up(cur);
       if(TR[TR[cur].ch[d]].id < TR[cur].id) rotate(cur,d);
    }
    int kth(int cur,int now) {
       while(1) {
          if(now > TR[ls].siz + TR[cur].cnt) now -= TR[ls].siz + TR[cur].cnt,cur = rs;
          else if(now <= TR[ls].siz) cur = ls;
          else return TR[cur].val;
       }
    }
    int rt,n,a[N];
    ll sum[N],ans[N][N];
    ll find(int cur,int val) {
       if(!cur) return 0;
       if(val >= TR[cur].val) return find(rs,val) + TR[ls].VAL + TR[cur].val * TR[cur].cnt;
       return find(ls,val);
    }
    int main() {
       n = read();
       int m = read();
       for(int i = 1;i <= n;++i) a[i] = read(),sum[i] = sum[i-1] + a[i];
       for(int i = 1;i <= n;++i) {
          rt = tot = 0;
          for(int j = i;j <= n;++j) {
             insert(rt,a[j]);
             int z = kth(rt,(j - i + 2) / 2);
             ll k = find(rt,z);
             if((j - i) & 1)   ans[i][j] = sum[j] - sum[i-1] - k * 2;
             else ans[i][j] = sum[j] - sum[i-1] - k * 2 + z;
          }
       }
       ll anss = 0;
       while(m--) anss += ans[read()][read()];
       cout<<anss;
       return 0;
    }
    

    一言

    易碎的 骄傲着 那也曾是我的模样。

  • 相关阅读:
    ASP.NET Core Docker部署
    Asp.net core WebApi 使用Swagger生成帮助页实例
    C#图片文字识别
    C#实现rabbitmq 延迟队列功能
    Windows下当地RabbitMQ服务的安装
    看大数据时代下的IT架构(1)业界消息队列对比
    查看sqlserver被锁的表以及如何解锁
    如何让win2008服务器显示中文无乱码
    Lucene.Net的服务器封装+APi组件 (开源)
    Oracle学习系列4
  • 原文地址:https://www.cnblogs.com/wxyww/p/10053251.html
Copyright © 2020-2023  润新知