题目大意:$N$ 件物品摆成一排,给每个物品定义两个属性 $A$ 和$ B$,两件物品的 差异度 定义为它们两种属性的差的绝对值中较大的一个。如果要求出一些物品的差异度,我们先定义一个 理想物品,使它与这些物品中每个物品的差异度的和最小,这些物品的差异度就是这个最小的和。给定$ N$ 个物品和Q组询问,询问从 $L $到 $R$ 的物品差异度为多少。

我们设物品$i$和物品$j$之间的差异度为$D$,则

$D=max\{|A_i-A_j|,|B_i-B_j|\}$

$=max\{A_i-A_j,A_j-A_i,B_i-B_j,B_j-B_i\}$

我们令$X_i=A_i+B_i,X_j=A_j+B_j,Y_i=A_i-B_i,Y_j=A_j-B_j$。

则有$D=max\{(X_i-X_j)+(Y_i-Y_j),(X_i-X_j)-(Y_i-Y_j),-(X_i-X_j)+(Y_i-Y_j),-(X_i-X_j)-(Y_i-Y_j)\}$

简单化简后,$D=|X_i-X_j|+|Y_i-Y_j|$。

对于每一件物品,我们求出其对应的$X$值和$Y$值。

我们建两棵主席树,分别维护$X$值和$Y$值。

查询一个区间时,我们在两棵主席树上分别查询区间中位数,然后随便维护一下就行了。

时间复杂度:$O(n\log\ n)$。

 #include<bits/stdc++.h>
#define M 100005
#define L long long
#define INF (2e9)
using namespace std; L n,q,A[M]={},B[M]={}; L lc[M*]={},rc[M*]={},siz[M*]={},cnt=; L sum[M*]={};
L root1[M]={},root2[M]={};
void add(L &x,L l,L r,L now){
cnt++; lc[cnt]=lc[x]; rc[cnt]=rc[x];
siz[cnt]=siz[x]+; sum[cnt]=sum[x]+now; x=cnt;
if(l==r) return; L mid=(l+r)>>;
if(now<=mid) add(lc[x],l,mid,now);
else add(rc[x],mid+,r,now);
}
L getkth(L x,L y,L l,L r,L k){
if(l==r) return l;
L mid=(l+r)>>;
if(siz[lc[y]]-siz[lc[x]]<k) return getkth(rc[x],rc[y],mid+,r,k-(siz[lc[y]]-siz[lc[x]]));
return getkth(lc[x],lc[y],l,mid,k);
}
L getsum(L x,L l,L r,L ll,L rr){
if(ll<=l&&r<=rr) return sum[x];
L mid=(l+r)>>,res=;
if(ll<=mid) res+=getsum(lc[x],l,mid,ll,rr);
if(mid<rr) res+=getsum(rc[x],mid+,r,ll,rr);
return res;
} main(){
scanf("%lld%lld",&n,&q);
for(L i=;i<=n;i++) scanf("%lld",A+i);
for(L i=;i<=n;i++) scanf("%lld",B+i);
for(L i=;i<=n;i++){
L upd1=A[i]+B[i],upd2=A[i]-B[i];
root1[i]=root1[i-]; root2[i]=root2[i-];
add(root1[i],-INF,INF,upd1);
add(root2[i],-INF,INF,upd2);
}
while(q--){
L l,r,k,h;L res=,mid; scanf("%lld%lld",&l,&r);
h=(r-l)/+; mid=(l+r)>>;
k=getkth(root1[l-],root1[r],-INF,INF,h);
res+=getsum(root1[r],-INF,INF,k,INF)-getsum(root1[l-],-INF,INF,k,INF);
res-=k*(r-mid+);
res+=(mid-l)*k;
res-=getsum(root1[r],-INF,INF,-INF,k-)-getsum(root1[l-],-INF,INF,-INF,k-); k=getkth(root2[l-],root2[r],-INF,INF,h);
res+=getsum(root2[r],-INF,INF,k,INF)-getsum(root2[l-],-INF,INF,k,INF);
res-=k*(r-mid+);
res+=(mid-l)*k;
res-=getsum(root2[r],-INF,INF,-INF,k-)-getsum(root2[l-],-INF,INF,-INF,k-); printf("%.2lf\n",0.5*res);
}
}

【xsy1144】选物品 主席树的更多相关文章

  1. [xsy1144]选物品

    题意:给定$a_{1\cdots n},b_{1\cdots n}$,询问是给定$l,r$,找出$a',b'$使得$\sum\limits_{i=l}^r\max(\left|a'-a_i\right ...

  2. 4.24 省选模拟赛 欧珀瑞特 主席树 可持久化trie树

    很容易的一道题目.大概.不过我空间计算失误MLE了 我草草的计算了一下没想到GG了. 关键的是 我学了一个dalao的空间回收的方法 但是弄巧成拙了. 题目没有明确指出 在任意时刻数组长度为有限制什么 ...

  3. PAT (Basic Level) Practise 1045 快速排序(离散化+主席树区间内的区间求和)

    1045. 快速排序(25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 著名的快速排序算法里有一个经典的划分 ...

  4. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

  5. BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案)

    BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案) 题意 : 给你一个长为\(R\)宽为\(C\)的矩阵,第\(i\)行\(j\)列的数为\(P_{i,j}\). 有\(m\)次 ...

  6. 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题

    “队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄>     线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...

  7. bzoj 2653 middle 二分答案 主席树判定

    判断中位数是否可行需要将当前的解作为分界,大于其的置为1,小于为-1,然后b-c必选,ab,cd可不选,这个用线段树判定就好 但不能每次跑,所以套主席树,按权值排序,构建主席树,更新时将上一个节点改为 ...

  8. codeforces 813E 主席树

    题意: 一个数列多组询问,每次询问[l,r]中最多能选多少个数字,其中每个数字的出现次数不超过k次 题解: 我们保存对于每个位置上,出现超过k次的位置,那么对于每次询问,我们就变成了查询区间[l,r] ...

  9. 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )

    在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...

随机推荐

  1. 2018.10.19 NOIP训练 变化的序列(线性dp)

    传送门 f[i][j]f[i][j]f[i][j]表示后iii个对答案贡献有jjj个a的方案数. 可以发现最后a,ba,ba,b的总个数一定是n∗(n−1)/2n*(n-1)/2n∗(n−1)/2 因 ...

  2. 2018.09.29 bzoj3039: 玉蟾宫(悬线法)

    传送门 悬线法的板子题. 悬线法只需要保存当期点向下最多多少个,把这个当成一条线,再处理出线绷直之后最多能向左右延展多少就行了. 代码: #include<bits/stdc++.h> # ...

  3. 2018.08.31 bzoj1419 Red is good(期望dp)

    描述 桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付 出1美元.可以随时停止翻牌,在最优策略下平均能得到多少钱. 输入 一行输入两个数R,B,其 ...

  4. 如何使用Java执行cmd命令

    用JAVA代码实现执行CMD命令的方法! Runtime rt = Runtime.getRuntime(); Process p = rt.exec(String[] cmdarray);     ...

  5. stdafx.h、stdafx.cpp是干什么用的?为什么我的每一个cpp文件都必须包含stdafx.h? Windows和MFC的include文件都非常大,即使有一个快速的处理程序,编

    sstdafx.h.stdafx.cpp是干什么用的?为什么我的每一个cpp文件都必须包含stdafx.h? Windows和MFC的include文件都非常大,即使有一个快速的处理程序,编译程序也要 ...

  6. Linux下的ICMP反弹后门:PRISM

    搜索的时候无意中看见的这款基于ping的ICMP后门.于是到作者的github上看看,居然是阴文的,为了过级,只能强忍着看了,学生狗伤不起.还好比较简单易懂,正如简介说的一样:“PRISM is an ...

  7. 99 Times--Kate Voegele

    歌手 Kate Voegele 是美国俄亥俄州的一位年轻创作型歌手,她会唱歌.会写歌.特 别擅长弹吉他.还会弹钢琴.她是美国新生代歌手中的佼佼者. 99 Times--Kate Voegele   S ...

  8. Android-普通菜单Menu

    第一种方式,使用Java方式 第二种方式,使用menu.xml package liudeli.activity; import android.app.Activity; import androi ...

  9. Android SharedPreference

    在Android开发过程中,Android提供了SharedPreference共享首选项,它的用途就是,用于保存软件配置信息,APP使用过程中,需要用到的配置信息,例如:音量大小等: SharedP ...

  10. DAC--解决windows验证无法登陆的问题

    解决思路: 使用单用户管理员模式启动SQL Server,再使用SQLCMD连接上数据库,此时有sysadmin权限,添加用户并赋予相应权限 1>停止SQL Server服务运行 2>在C ...