BZOJ5319/LOJ2551「JSOI2018」列队
问题描述
作为一名大学生,九条可怜在去年参加了她人生中的最后一次军训。
军训中的一个重要项目是练习列队,为了训练学生,教官给每一个学生分配了一个休息位置。每次训练开始前,所有学生都在各自的休息位置休息,但是当教官发出集合命令后,被点到的学生必须要到指定位置集合。
为了简化问题,我们把休息位置和集合位置抽象成一根数轴。一共有 \(n\) 个学生,第 \(i\) 个学生的休息位置是 \(a_i\)。每一次命令,教官会指定一个区间 \([l,r]\) 和集合点 \(K\) ,所有编号在 \([l,r]\) 内的学生都必须赶到集合点列队。在列队时,每一个学生需要选择 \([K,K+r-l]\) 中的一个整数坐标站定且不能有任何两个学生选择的坐标相同。学生从坐标 \(x\) 跑到坐标 \(y\) 需要耗费体力 \(|y-x|\) 。
在一天的训练中,教官一共发布了 \(m\) 条命令 \((l,r,K)\) ,现在你需要计算对于每一条命令,在所有可能的列队方案中,消耗的体力值总和最小是多少。
以下是对题意的一些补充:
- 任何两条命令是无关的,即在一条集合命令结束后,所有学生都会回到自己的休息位置,然后教官才会发出下一条命令。
- 在集合的时候,可能有编号不在 \([l,r]\) 内的学生处在区间 \([K,K+r-l]\) 中,这时他会自己跑开,且跑动的距离不记在消耗的体力值总和中。
题解
显然,不原相对顺序更优。
因此答案为 \(\sum\limits_{i=l}^r{a_i+rk_i-k-1}\) 。
把这个式子拆掉绝对值,就变为了向左跑和向右跑的两种情况。
在可持久化权值线段树上记录 \(\sum a_i\) 即可。
\(\mathrm{Code}\)
从今天起更改码风。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 500007;
const int maxs = 11000007;
const int s = 1000000;
int n, T;
int rt[maxn];
int ls[maxs], rs[maxs], cnt;
int size[maxs];
LL sum[maxs];
void Insert(int &x ,int l, int r, int val) {
ls[++cnt] = ls[x], rs[cnt] = rs[x], size[cnt] = size[x] + 1, sum[cnt] = sum[x] + (LL)val;
x = cnt;
if(l == r) return ;
int mid = (l + r) >> 1;
if(val <= mid) Insert(ls[x], l, mid, val);
else Insert(rs[x], mid + 1, r, val);
}
int k;
LL Query(int rt1, int rt2, int l, int r, int st) {
if(size[rt1] - size[rt2] == 0) return 0ll;
LL sz = size[rt1] - size[rt2], sigma = sum[rt1] - sum[rt2];
if(l >= k + st) return sigma - sz * (2 * st + 2 * k + sz - 1) / 2;
if(r <= k + st + sz - 1) return sz * (2 * st + 2 * k + sz - 1) / 2 - sigma;
int mid = (l+r) >> 1;
return Query(ls[rt1], ls[rt2], l, mid, st) + Query(rs[rt1], rs[rt2], mid + 1, r, st + size[ls[rt1]] - size[ls[rt2]]);
}
void Init(void) {
scanf("%d%d", &n, &T);
for(int i = 1, x; i <= n; i++) {
scanf("%d", &x);
rt[i] = rt[i-1];
Insert(rt[i], 1, s, x);
}
}
void Work(void) {
while(T--) {
int l, r;
scanf("%d%d%d", &l, &r, &k);
printf("%lld\n",Query(rt[r], rt[l-1], 1, s, 0));
}
}
int main() {
Init();
Work();
return 0;
}
BZOJ5319/LOJ2551「JSOI2018」列队的更多相关文章
- LOJ 2551 「JSOI2018」列队——主席树+二分
题目:https://loj.ac/problem/2551 答案是排序后依次走到 K ~ K+r-l . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...
- 【LOJ】#2551. 「JSOI2018」列队
题解 老年选手一道裸的主席树都要看好久才看出来 首先熟练的把这个区间建成\(n\)个主席树 然后对于一个询问,我们相当于在主席树上二分一个mid,使得\(mid - K + 1\)正好和\([l,r] ...
- 「JSOI2018」战争
「JSOI2018」战争 解题思路 我们需要每次求给一个凸包加上一个向量后是否与另外一个凸包相交,也就是说是否存在 \[ b\in B,(b+w)\in A \] 这里 \(A, B\) 表示凸包内部 ...
- BZOJ5319 & 洛谷4559 & LOJ2551:[JSOI2018]军训列队——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5319 https://www.luogu.org/problemnew/show/P4559 ht ...
- LOJ 2550 「JSOI2018」机器人——找规律+DP
题目:https://loj.ac/problem/2550 只会写20分的搜索…… #include<cstdio> #include<cstring> #include&l ...
- LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流
题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...
- LOJ 2547 「JSOI2018」防御网络——思路+环DP
题目:https://loj.ac/problem/2547 一条树边 cr->v 会被计算 ( n-siz[v] ) * siz[v] 次.一条环边会被计算几次呢?于是去写了斯坦纳树. #in ...
- LOJ #2547 Luogu P4517「JSOI2018」防御网络
好像也没那么难写 LOJ #2547 Luogu P4517 题意 在一棵点仙人掌中等概率选择一个点集 求选出点集的斯坦纳树大小的期望 定义点仙人掌为不存在一个点在多个简单环中的连通图 斯坦纳树为在原 ...
- LOJ 2546 「JSOI2018」潜入行动——树形DP
题目:https://loj.ac/problem/2546 dp[ i ][ j ][ 0/1 ][ 0/1 ] 表示 i 子树,用 j 个点,是否用 i , i 是否被覆盖. 注意 s1<= ...
随机推荐
- Learn from Niu 2020.1.21
1. 你一定要看计算机领域的文章. 如果你是看一堆应用,你最终还是会不知道怎么做. 从计算机到energy是降维打击, 当你学习了计算机的hot skill,再去做应用很容易. 2. 搞研究的思路: ...
- Spectral clustering谱聚类
Basic knowledge: degree matrix; similarity matrix, and Adjacency matrix; 无向带权图模型 G=<V,E>G=< ...
- 【原】librtmp源码详解
“悟已往之不谏,知来者之可追”.后悔做了这么久的直播,却不曾理解rtmp协议的实现原理,现在意识到了这个问题,特此补救.同时谨以此文纪念曾经的雷霄骅同学,感谢他对音视频领域做出的卓越贡献和引领. 1. ...
- MyEclipse 安装及激活教程
一.下载安装MyEclipse 在进行下面的步骤之前,先安装好MyEclipse (10.0.2015版本或更高版本)和JDK,安装完成后暂时不要运行MyEclipse. 二.运行MyEclipse激 ...
- AcWing 两个简单的位运算操作
//是柱状数组的一个基操作 //返回n的最后一位1:lowbit(n) = n & -n //比如 x=1010 那么返回10 x=101000 返回1000 #include<bits ...
- group by分组后对组内数据进行排序
查询 每个班级英语成绩最高的前两名的记录 原文:https://www.cnblogs.com/hxfcodelife/p/10226934.html select a.Classid,a.Engli ...
- 题解【洛谷P1074】[NOIP2009]靶形数独
题面 题解 一开始写了一个朴素的数独,无任何剪枝优化,得到了\(55\)分的好成绩. 就是这道题加一个计算分数. 代码如下(\(\mathrm{55\ pts}\)): /************** ...
- 题解【loj6277】数列分块入门1
题目描述 给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字\(n\). 第二行输入\(n\)个数字,第\(i\)个数字为\(a_{i}\) ...
- webpack4.41.0配置一(基础配置webpack文件,入口出口,实现打包)
1.查看node.js版本.npm版本和webpack版本(使用webpack4时,请确保node.js的版本>=8.9.4) 2.我先重新卸载了webpack和webpack-cli(全局) ...
- Atcoder Beginner Contest 155D(二分,尺取法,细节模拟)
二分,尺取法,细节模拟,尤其是要注意a[i]被计算到和a[i]成对的a[j]里时 #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> ...