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 . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...
随机推荐
- pyhton3 sys模块
Python常用模块之sys sys模块提供了一系列有关Python运行环境的变量和函数. 1 ). sys.stdin 标准输入流.2 ).sys.stdout 标准输出流.3 ). sys.std ...
- Yii2 自定义独立验证器
新建一个文件: ?php /** * author : forecho <caizhenghai@gmail.com> * createTime : 2015/7/1 14:54 * de ...
- C# partial 关键字
C# partial关键字详解 partial关键字允许把类.结构或接口放在多个文件中.一般情况下,一个类存储在单个文件中.但有时,多个开发人员需要访问同一个类,或者某种类型的代码生成器生成了一个类的 ...
- flex datagrid 导出csv
public function exportToCSV(dataGrid:DataGrid):void { var dataProviderCollection:ArrayCollection = d ...
- 建议10:numpy使用基础
# -*- coding: utf-8 -*- import numpy as np #---------------------------------------- #-- 定义 ndarray ...
- 【TECH】CAS php客户端配置
搞完java又搞php,我整个人都不好了=.= 跟大师在linux上折腾了一下午,没调出来,早上在windows上跑通了,中午终于在linux上搞定了,嘿嘿. server端配置参见这里 在windo ...
- 继承Thread类与实现Runnable接口
java中创建线程有两种方式: 1. 类继承Thread类,重写run方法,每创建一个实例对象即开启一个线程 2. 类实现Runnable接口,重写run方法,将实例对象传入新建Thread的方法: ...
- cocos2dx打飞机项目笔记三:HeroLayer类和坐标系
HeroLayer类主要是处理hero的一些相关东西,以及调用bulletLayer的一些方法,因为子弹是附属于hero的~~ HeroLayer 类的成员如下: class HeroLayer : ...
- 大话设计模式之PHP篇 - 单例模式
在编写PHP代码的时候,经常使用new关键字实例化一个对象,比如 <?php Class Database { } $db = new Database; 这是最常规的实例化操作方法,像数据库操 ...
- recovery 差分升级包制作超时【转】
本文转载自:https://blog.csdn.net/csdn66_2016/article/details/73800349 我们在对android系统升级的时候,可以减少升级包的大小,只升级差异 ...