BZOJ5319: [Jsoi2018]军训列队
BZOJ5319: [Jsoi2018]军训列队
https://lydsy.com/JudgeOnline/problem.php?id=5319
分析:
- 易知把所有人按原本的顺序放到\([K,K+len-1]\)这些位置上是最优的。
- 我们只需要求一个\(mid\), 满足从\(mid\)以后的人都是向左移动。
- 这个可以用二分+主席树在\(O(nlog^2)\)的时间内解决, 然后过不去。
- 变成直接在主席树上二分就好了,需要一点小技巧。
- 即二分走的区间不一定包含答案点,但可能是答案点减\(1\), 在叶子上特判即可。
代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long ll;
#define N 500050
#define M 1500000
int n,m,a[N];
int siz[N*30],ls[N*30],rs[N*30],cnt,root[N];
ll sum[N*30];
void update(int l,int r,int x,int &p,int q) {
p=++cnt; ls[p]=ls[q]; rs[p]=rs[q]; siz[p]=siz[q]+1; sum[p]=sum[q]+x;
if(l==r) return ;
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,x,ls[p],ls[q]);
else update(mid+1,r,x,rs[p],rs[q]);
}
ll c,now,s[N];
ll S(ll l,ll r) {return (l+r)*(r-l+1)/2;}
ll query(int l,int r,int p,int q) {
if(l==r) {
if(siz[p]>siz[q]&&l<now) {c++; return l;}
else return 0;
}
int mid=(l+r)>>1,sizls=siz[ls[p]]-siz[ls[q]];
if(!sizls) return query(mid+1,r,rs[p],rs[q]);
if(mid<=now+sizls-1) {
c+=sizls, now+=sizls;
return query(mid+1,r,rs[p],rs[q])+sum[ls[p]]-sum[ls[q]];
}else return query(l,mid,ls[p],ls[q]);
}
int main() {
scanf("%d%d",&n,&m);
int i,l,r,k;
for(i=1;i<=n;i++) scanf("%d",&a[i]),s[i]=s[i-1]+a[i],update(1,M,a[i],root[i],root[i-1]);
while(m--) {
scanf("%d%d%d",&l,&r,&k);
now=k; c=0;
ll tot=query(1,M,root[r],root[l-1]);
ll ans=S(k,k+c-1)-tot + s[r]-s[l-1]-tot-S(k+c,k+r-l);
printf("%lld\n",ans);
}
}
BZOJ5319: [Jsoi2018]军训列队的更多相关文章
- 【BZOJ5319】军训列队(主席树)
[BZOJ5319]军训列队(主席树) 题面 BZOJ 洛谷 题解 一眼题既视感... 首先很明显,每次询问的结果显然是做一次离散. 然后直接上主席树就好了... 查询答案的方式也很简单 考虑一下那个 ...
- [JSOI2018]军训列队
[JSOI2018]军训列队 题目大意: \(n(n\le5\times10^5)\)个学生排成一排,第\(i\)个学生的位置为\(a_i\).\(m(m\le5\times10^5)\)次命令,每次 ...
- BZOJ5319 & 洛谷4559 & LOJ2551:[JSOI2018]军训列队——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5319 https://www.luogu.org/problemnew/show/P4559 ht ...
- BZOJ.5319.[JSOI2018]军训列队(主席树)
LOJ BZOJ 洛谷 看错了,果然不是\(ZJOI\)..\(jry\)给\(JSOI\)出这么水的题做T3么= = 感觉说的有点乱,不要看我写的惹=-= 对于询问\(l,r,k\),设\(t=r- ...
- 洛谷 P4559: bzoj 5319: [JSOI2018]军训列队
题目传送门:洛谷 P4559. 题意简述: 有 \(n\) 个学生,编号为 \(i\) 的学生有一个位置 \(a_i\). 有 \(m\) 个询问,每次询问编号在 \([l,r]\) 区间内的学生跑到 ...
- bzoj 5319: [Jsoi2018]军训列队
Description Solution 最优情况可以是所有人按位置从小到大排序之后依次占到自己 \(K+\) 排名的位置上去 因为每一个休息位置不同,那么一定递增,所以一定存在一个分界点,左边的是往 ...
- BZOJ5319/LOJ2551「JSOI2018」列队
问题描述 作为一名大学生,九条可怜在去年参加了她人生中的最后一次军训. 军训中的一个重要项目是练习列队,为了训练学生,教官给每一个学生分配了一个休息位置.每次训练开始前,所有学生都在各自的休息位置休息 ...
- BZOJ5319 JSOI2018列队(主席树)
显然集合后相对位置不变最优.主席树上二分向左和向右的分界点即可.注意主席树的值域.我怎么天天就写点一眼题啊. #include<iostream> #include<cstdio&g ...
- LOJ 2551 「JSOI2018」列队——主席树+二分
题目:https://loj.ac/problem/2551 答案是排序后依次走到 K ~ K+r-l . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...
随机推荐
- input propertychange(1)
input type=“text” 通过js改变输入框的value值是不会出发input propertychange事件
- linux练习命令
任务一:按要求完成以下操作1)显示日期格式2)在/tmp/下新建目录test ,并指定权限6643)显示环境变量path,但将/root加入到$PATH中4)用cat显示/etc/passwd,并打印 ...
- SQL Server获取数据库的当前连接状态
SELECT * FROM [Master].[dbo].[SYSPROCESSES] WHERE [DBID]=(SELECT [DBID] FROM [Master].[dbo].[SYSDATA ...
- JAVAWeb学习总结(一)
一.基本概念 1.1.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 静态web资源( ...
- Java 内部类、静态类内部类
问: 什么是内部类? 答: 内部类(Inner Class)就是在一个类的内部再定义一个类,与之对应包含内部类的类被称为外部类. 问: 为什么要将一个类定义在另外一个类内部呢? 答: 内部类主要作用如 ...
- Kubernetes Metrics-Server
github地址:https://github.com/kubernetes-incubator/metrics-server 官网介绍:https://kubernetes.io/docs/task ...
- 0x5C 计数类DP
cf 559C 考虑到黑色的格子很少,那么我把(1,1)变成黑色,然后按每个黑色格子接近终点的程度排序,计算黑色格子不经过另一个黑色格子到达终点的方案,对于当前的格子,要减去在它右下角的所有方案数(注 ...
- Linux系统LVM分区减容扩容
Linux系统LVM分区减容扩容 目标:将VolGroup-lv_home缩小到20G,并将剩余的空间添加给VolGroup-lv_root 1.首先查看磁盘使用情况 [root@localhost ...
- IntelliJ Idea中配置、使用技巧(持续更新)
当前项目配置和全局配置 idea中的File-->settings...和File-->other settings-->Default settings...分别是对当前项目的配置 ...
- tyvj 1884 [NOIP2000T4]方格取数 || codevs 1043 dp
P1884 [NOIP2000T4]方格取数 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 [noip2000T4]方格取数 描述 设有N*N的方格图(N& ...