Description:

作为一名大学生,九条可怜在去年参加了她人生中的最后一次军训。

军训中的一个重要项目是练习列队,为了训练学生,教官给每一个学生分配了一个休息位置。每次训练开始前,所有学生都在各自的休息位置休息,但是当教官发出集合命令后,被点到的学生必须要到指定位置集合。

为了简化问题,我们把休息位置和集合位置抽象成一根数轴。一共有 \(n\) 个学生,第 \(i\) 个学生的休息位置是 \(a_i\)​。每一次命令,教官会指定一个区间 \([l,r]\) 和集合点 \(K\) ,所有编号在 \([l,r]\) 内的学生都必须赶到集合点列队。在列队时,每一个学生需要选择 \([K,K+r-l]\) 中的一个整数坐标站定且不能有任何两个学生选择的坐标相同。学生从坐标 \(x\) 跑到坐标 \(y\) 需要耗费体力 \(\vert y-x \vert\) 。

在一天的训练中,教官一共发布了 \(m\) 条命令 \((l,r,K)\) ,现在你需要计算对于每一条命令,在所有可能的列队方案中,消耗的体力值总和最小是多少。

以下是对题意的一些补充:

任何两条命令是无关的,即在一条集合命令结束后,所有学生都会回到自己的休息位置,然后教官才会发出下一条命令。

在集合的时候,可能有编号不在 \([l,r]\) 内的学生处在区间 \([K,K+r-l]\) 中,这时他会自己跑开,且跑动的距离不记在消耗的体力值总和中。

Hint:

\(n,m \le 10^5,a_i,k \le 10^6\)

Solution:

都是列队,都是毒瘤题,懂的都懂

好吧其实也不算毒瘤

思路很容易想到,就是集合的相对顺序与休息时的相对顺序一样时体力值和取到最小

关键是怎么统计这个最小值

可以发现所有人可以分成向左走和向右走

向左走的贡献: \(\sum k+rk_i-1-a_i\)

向右走的贡献: \(\sum a_i-k+rk_i-1\)

\(\sum a_i\) 是定值 \(\sum k+rk_i-1\) 是个等差数列,直接算就行

如何判断向左向右呢? 魔改版主席树一直递归左右区间求解,具体看代码

  1. #include <map>
  2. #include <set>
  3. #include <stack>
  4. #include <cmath>
  5. #include <queue>
  6. #include <cstdio>
  7. #include <cstring>
  8. #include <cstdlib>
  9. #include <iostream>
  10. #include <algorithm>
  11. using namespace std;
  12. typedef long long ll;
  13. const int bd=1e6+5,mxn=5e5+5,mxm=2e7+5;
  14. int n,m,cnt,a[mxn],hd[mxn];
  15. int rt[mxm],ls[mxm],rs[mxm],sz[mxm];
  16. ll sum[mxm];
  17. inline int read() {
  18. char c=getchar(); int x=0,f=1;
  19. while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
  20. while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
  21. return x*f;
  22. }
  23. inline void chkmax(int &x,int y) {if(x<y) x=y;}
  24. inline void chkmin(int &x,int y) {if(x>y) x=y;}
  25. struct ed {
  26. int to,nxt;
  27. }t[mxn<<1];
  28. inline void add(int u,int v) {
  29. t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
  30. }
  31. void update(int las,int &p,int l,int r,int val)
  32. {
  33. if(!p) p=++cnt; sz[p]=sz[las]+1; sum[p]=sum[las]+val;
  34. if(l==r) return ; int mid=(l+r)>>1;
  35. if(val<=mid) update(ls[las],ls[p],l,mid,val),rs[p]=rs[las];
  36. else update(rs[las],rs[p],mid+1,r,val),ls[p]=ls[las];
  37. }
  38. ll query(int las,int p,int l,int r,int s,int k)
  39. {
  40. if(!p) return 0;
  41. ll num=sz[p]-sz[las],val=sum[p]-sum[las];
  42. if(l>=k+s) return val-(2*k+2*s+num-1)*num/2;
  43. if(r<=k+s+num-1) return (2*k+2*s+num-1)*num/2-val;
  44. int mid=(l+r)>>1; num=sz[ls[p]]-sz[ls[las]];
  45. return query(ls[las],ls[p],l,mid,s,k)+query(rs[las],rs[p],mid+1,r,s+num,k);
  46. }
  47. int main()
  48. {
  49. n=read(); m=read(); int l,r,k;
  50. for(int i=1;i<=n;++i) a[i]=read(),update(rt[i-1],rt[i],1,bd,a[i]);
  51. for(int i=1;i<=m;++i) {
  52. l=read(); r=read(); k=read();
  53. printf("%lld\n",query(rt[l-1],rt[r],1,bd,0,k));
  54. }
  55. return 0;
  56. }

[JSOI2018]列队的更多相关文章

  1. [JSOI2018]列队(主席树)

    跟上次那道列队不一样,但都是九条可怜...(吉老师太强了) 在主席树上统计答案,因为值域只有 \(10^6\) 甚至不用离散化... \(Code\ Below:\) #include <bit ...

  2. P4559 [JSOI2018]列队

    \(\color{#0066ff}{ 题目描述 }\) 作为一名大学生,九条可怜在去年参加了她人生中的最后一次军训. 军训中的一个重要项目是练习列队,为了训练学生,教官给每一个学生分配了一个休息位置. ...

  3. BZOJ5319 JSOI2018列队(主席树)

    显然集合后相对位置不变最优.主席树上二分向左和向右的分界点即可.注意主席树的值域.我怎么天天就写点一眼题啊. #include<iostream> #include<cstdio&g ...

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

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

  5. 洛谷P4559 [JSOI2018]列队(主席树)

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

  6. [JSOI2018]军训列队

    [JSOI2018]军训列队 题目大意: \(n(n\le5\times10^5)\)个学生排成一排,第\(i\)个学生的位置为\(a_i\).\(m(m\le5\times10^5)\)次命令,每次 ...

  7. BZOJ5319: [Jsoi2018]军训列队

    BZOJ5319: [Jsoi2018]军训列队 https://lydsy.com/JudgeOnline/problem.php?id=5319 分析: 易知把所有人按原本的顺序放到\([K,K+ ...

  8. BZOJ5319/LOJ2551「JSOI2018」列队

    问题描述 作为一名大学生,九条可怜在去年参加了她人生中的最后一次军训. 军训中的一个重要项目是练习列队,为了训练学生,教官给每一个学生分配了一个休息位置.每次训练开始前,所有学生都在各自的休息位置休息 ...

  9. BZOJ.5319.[JSOI2018]军训列队(主席树)

    LOJ BZOJ 洛谷 看错了,果然不是\(ZJOI\)..\(jry\)给\(JSOI\)出这么水的题做T3么= = 感觉说的有点乱,不要看我写的惹=-= 对于询问\(l,r,k\),设\(t=r- ...

随机推荐

  1. AI学习吧-REDIS-常识

    Redis 是一个non-sql,非关系型数据库,数据存放在内存中,支持持久化,redis中的数据会在一段时间内和(mysql等数据库)磁盘进行同步,防止丢失,这样也就降低了读数据效率. Redis和 ...

  2. NPOI操作Excel(一)--NPOI基础

    用C#读取Excel的方法有很多中,由于近期工作需要,需要解析的Excel含有合并单元格以及背景色等特殊要求,故在网上查了一些关于读Excel的方法的优缺点,觉得NPOI能满足我的需要,所以搜索了一些 ...

  3. 论文阅读笔记三十八:Deformable Convolutional Networks(ECCV2017)

    论文源址:https://arxiv.org/abs/1703.06211 开源项目:https://github.com/msracver/Deformable-ConvNets 摘要 卷积神经网络 ...

  4. Python模拟人猜数过程(折半查找)

    import random# (0,1000)随机产生一个数key = random.randint(1,1000)# 用来统计猜的次数count = 0 # 定义一个折半查找的函数def BinSe ...

  5. 插件使用一表单验证一validation

    jquery-validation是一款前端经验js插件,可以验证必填字段.邮件.URL.数字范围等,在表单中应用非常广泛. 官方网站 https://jqueryvalidation.org/ 源码 ...

  6. python网络爬虫day1

    python爬虫真的很方便,自己不能忽视的问题就是字符编码的问题,一直想腾出时间来看,一直没有时间.明天开始看吧. 今天是学习python爬虫的第一天,从B站上搜到的,可惜可惜. import req ...

  7. exec函数族

    进程程序替换 进程程序替换原理 fork创建子进程执行的是和父进程相同的程序(也有可能是某个分支),通常fork出的子进程是为了完成父进程所分配的任务,所以子进程通常会调用一种exec函数(六种中的任 ...

  8. 用SQL语句查询zabbix的监控数据

    参考地址:http://blog.51cto.com/sfzhang88/1558254 -- 获取主机id -- 10084 select hostid from hosts where host= ...

  9. [转] 合理使用npm version与npm dist-tag详解

    第一步:发布第一个稳定版本 npm publish//1.0.0 第二步:修改文件继续发布第二个版本 git add -A && git commit -m "c" ...

  10. UICollectionView的常用方法

    class UICollectionView : UIScrollView //初始化,位置,风格 init(frame: CGRect, collectionViewLayout layout: U ...