题面

传送门

题解

首先考虑一个贪心,我们把所有的人按\(a_i\)排个序,那么排序后的第一个人到\(k\),第二个人到\(k+1\),...,第\(i\)个人到\(k+i-1\),易证这样一定是最优的

然后发现这里有一个很重要的性质,\(a_i\)互不相同。那么就必定存在一个点\(mid\),在\(mid\)左边(包括\(mid\))的空格子和人一样多,右边(不包括\(mid\))也一样多

那么很明显,\(mid\)左边的所有人都需要往右跑,\(mid\)右边的所有人都需要往左跑

然后来康康答案啊……先看看\(mid\)左边,第一个人要跑\(k-a_1\),第二个人要跑\(k+1-a_2\),...,第\(mid-k+1\)个人要跑\(mid-a_{mid-k+1}\)……

这不就等价于\(\sum_{i=k}^{mid}i-\sum_{a_i\leq mid}a_i\)嘛!

也就是说,左边的答案就是\(k\)到\(mid\)的和,减去所有标号在\([l,r]\)区间内,且\(a_i\leq mid\)的\(a_i\)之和,一发主席树就搞定了。右边同理

顺便这个\(mid\)也可以在主席树上二分得到

//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R ll x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=5e5+5,M=(N<<5);
ll sum[M],Pre[N],ss,res;int sz[M],lc[M],rc[M],rt[N],a[N];
int n,m,l,r,k,cnt,zz,lim=2e6;
inline bool cmp(const int &x,const int &y){return a[x]<a[y];}
inline ll calc(R int l,R int r){return (1ll*r*(r+1)>>1)-(1ll*(l-1)*l>>1);}
void update(int &p,int q,int l,int r,int x){
p=++cnt,sz[p]=sz[q]+1,sum[p]=sum[q]+x;
if(l==r)return;int mid=(l+r)>>1;
x<=mid?(rc[p]=rc[q],update(lc[p],lc[q],l,mid,x)):
(lc[p]=lc[q],update(rc[p],rc[q],mid+1,r,x));
}
void query(int p,int q,int l,int r,int x){
if(!p||l==r)return zz+=sz[p]-sz[q],ss+=sum[p]-sum[q],void();
int mid=(l+r)>>1,res=mid-x+1;
zz+sz[lc[p]]-sz[lc[q]]<=res?query(lc[p],lc[q],l,mid,x):
(zz+=sz[lc[p]]-sz[lc[q]],ss+=sum[lc[p]]-sum[lc[q]],query(rc[p],rc[q],mid+1,r,x));
}
int main(){
// freopen("testdata.in","r",stdin);
// freopen("testdata.out","w",stdout);
n=read(),m=read();
fp(i,1,n)a[i]=read(),Pre[i]=Pre[i-1]+a[i],update(rt[i],rt[i-1],1,lim,a[i]);
while(m--){
l=read(),r=read(),k=read(),ss=zz=0;
query(rt[r],rt[l-1],1,lim,k);
res=calc(k,k+zz-1)-ss+Pre[r]-Pre[l-1]-ss-calc(k+zz,k+r-l);
print(res);
}
return Ot(),0;
}

洛谷P4559 [JSOI2018]列队(主席树)的更多相关文章

  1. 洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】

    题目链接 洛谷P4559 题解 只会做\(70\)分的\(O(nlog^2n)\) 如果本来就在区间内的人是不用动的,区间右边的人往区间最右的那些空位跑,区间左边的人往区间最左的那些空位跑 找到这些空 ...

  2. 洛谷P2617 Dynamic Rankings (主席树)

    洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...

  3. 洛谷P3567 KUR-Couriers [POI2014] 主席树/莫队

    正解:主席树/莫队 解题报告: 传送门! 这题好像就是个主席树板子题的样子,,,? 毕竟,主席树的最基本的功能就是,维护一段区间内某个数字的个数 但是毕竟是刚get到主席树,然后之前做的一直是第k大, ...

  4. 洛谷P3567[POI2014]KUR-Couriers(主席树+二分)

    题意:给一个数列,每次询问一个区间内有没有一个数出现次数超过一半 题解: 最近比赛太多,都没时间切水题了,刚好日推了道主席树裸题,就写了一下 然后 WA80 WA80 WA0 WA90 WA80 ?? ...

  5. 洛谷P3567 [POI2014]KUR-Couriers 主席树

    挺裸的,没啥可讲的. 不带修改的主席树裸题 Code: #include<cstdio> #include<algorithm> using namespace std; co ...

  6. 洛谷$P3302$ 森林 $[SDOI2013]$ 主席树

    正解:主席树 解题报告: 传送门! 口胡一时爽代码火葬场 这题想法不难,,,但显然的是代码应该还挺难打的 但反正我也不放代码,就写下题解趴$QwQ$ 第一问就是个$Count\ on\ a\ tree ...

  7. 洛谷P4602 [CTSC2018]混合果汁(主席树)

    题目描述 小 R 热衷于做黑暗料理,尤其是混合果汁. 商店里有 nn 种果汁,编号为 0,1,\cdots,n-10,1,⋯,n−1 . ii 号果汁的美味度是 d_idi​ ,每升价格为 p_ipi ...

  8. 洛谷P2617 Dynamic Rankings 主席树 单点修改 区间查询第 K 大

    我们将线段树套在树状数组上,查询前预处理出所有要一起移动的节点编号,并在查询过程中一起将这些节点移到左右子树上. Code: #include<cstdio> #include<cs ...

  9. 洛谷4137 mex题解 主席树

    题目链接 虽然可以用离线算法水过去,但如果强制在线不就gg了. 所以要用在线算法. 首先,所有大于n的数其实可以忽略,因为mex的值不可能大于n 我们来设想一下,假设已经求出了从0到n中所有数在原序列 ...

随机推荐

  1. numpy的一些用法

    安装numpy windows安装pip即可,具体方法参考pip官网 http://pip-cn.readthedocs.io/en/latest/installing.html 安装方法:pip i ...

  2. Sql Server 2005如何导入DBF文件?

    提问者采纳   select * into 要生成的SQL表名 from OPENROWSET('MICROSOFT.JET.OLEDB.4.0','dBase IV;HDR=NO;IMEX=2;DA ...

  3. leetcode717

    class Solution { public: bool isOneBitCharacter(vector<int>& bits) { int len = bits.size() ...

  4. Vulkan Tutorial 10 图形管线

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 通过接下来的章节,我们将会开启有关图形管线的话题,通过对图 ...

  5. Java多线程-新特征-信号量Semaphore

    简介信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确.合理的使用公共资源. 概念Semaphore分为单值和多值两种,前者只能 ...

  6. Bootstrap 学习资料

    1.Bootstrap中文文档 2.Bootstrap3.1.1 DEMO 3.Bootstrap教程 4.Sco.js--Bootstrap javascript组件的增强版 如果,您认为阅读这篇博 ...

  7. 基于Nginx实现集群原理

    1)安装Nginx 2)配置多个Tomcat,并修改端口号(两个端口号不一样即可) 3)在Nginx的Nginx.conf添加如下配置:

  8. Java 基于web service 暴露接口 供外部调用

    package cn.zr.out.outinterface; import java.text.SimpleDateFormat; import java.util.Date; import jav ...

  9. Ubuntu18.04创建新的系统用户

    目标: 1.为测试学习Docker,在虚拟机OS为18.04里,创建一个系统账号,账号名称:docker 2.在/home下有新建username的文件夹 一.建立账号 1.以root账号登录 2.u ...

  10. Linux中IO监控命令的使用分析

    一篇不错的有关linux io监控命令的介绍和使用. 1.系统级IO监控 iostat iostat -xdm 1    # 个人习惯 %util         代表磁盘繁忙程度.100% 表示磁盘 ...