51nod 1463找朋友
2016-12-23 22:06
218 查看
给定:
两个长度为n的数列A 、B
一个有m个元素的集合K
询问Q次
每次询问[l,r],输出区间内满足|Bi-Bj|∈K 的最大Ai+Aj
数据约定:
n,Q<=100000
m <= 10
0<=A[i]<=1000000000
1<=B[i]<=n
1<=K[i]<=n
保证B[i]互不相等
Input
n Q m
A1 A2 ….An
B1 B2 ….Bn
K1 K2 ….Km
l1 r1
l2 r2
.
.
lQ rQ
Output
Q行,每行一个整数表示相对应的答案。
如果找不到这样的两个数则输出0。
Input示例
4 2 2
1 2 3 4
3 2 1 4
1 3
1 4
2 3
Output示例
7
5
一开始根据b<=n直接就想到可以把所有的可行的BI,BJ全部求出来然后直接更新?然而没想到有什么数据结构能这么做。。
不得不看一波题解,感觉思路很巧妙。
先把询问按照右端点排序,然后每次左边界是固定的,所以只用考虑右边界,每次把范围内的合法对求出来然后在线段树里更新,注意这里的更新和普通的更新不同,因为线段树里存储的所有店实际上是1-i的区间最大答案,所以只要区间小于更新点的点全部都要更新,具体看代码。
两个长度为n的数列A 、B
一个有m个元素的集合K
询问Q次
每次询问[l,r],输出区间内满足|Bi-Bj|∈K 的最大Ai+Aj
数据约定:
n,Q<=100000
m <= 10
0<=A[i]<=1000000000
1<=B[i]<=n
1<=K[i]<=n
保证B[i]互不相等
Input
n Q m
A1 A2 ….An
B1 B2 ….Bn
K1 K2 ….Km
l1 r1
l2 r2
.
.
lQ rQ
Output
Q行,每行一个整数表示相对应的答案。
如果找不到这样的两个数则输出0。
Input示例
4 2 2
1 2 3 4
3 2 1 4
1 3
1 4
2 3
Output示例
7
5
一开始根据b<=n直接就想到可以把所有的可行的BI,BJ全部求出来然后直接更新?然而没想到有什么数据结构能这么做。。
不得不看一波题解,感觉思路很巧妙。
先把询问按照右端点排序,然后每次左边界是固定的,所以只用考虑右边界,每次把范围内的合法对求出来然后在线段树里更新,注意这里的更新和普通的更新不同,因为线段树里存储的所有店实际上是1-i的区间最大答案,所以只要区间小于更新点的点全部都要更新,具体看代码。
uses math; type node=record l,r,id:longint; end; var i,j,k,p,n,m,s,t,res,x,y:longint; b,a,c,tr,ans,re,d:array[0..400000]of int64; q:array[0..400000]of node; procedure qsort(l,r:longint); var i,j,m:longint; t:node; begin i:=l; j:=r; m:=q[(l+r)div 2].r; repeat while q[i].r<m do inc(i); while q[j].r>m do dec(j); if i<=j then begin t:=q[i]; q[i]:=q[j]; q[j]:=t; inc(i); dec(j); end; until i>j; if l<j then qsort(l,j); if i<r then qsort(i,r); end; procedure insert(x,l,r,num,v:longint); var m:longint; begin tr[x]:=max(tr[x],v); if (l=num)and(r=num)then exit; m:=(l+r)div 2; if num<=m then insert(x*2,l,m,num,v) else if num>m then insert(x*2+1,m+1,r,num,v); end; procedure find(x,l,r,l1,r1:longint); var m:longint; begin if (l=l1)and(r=r1)then begin res:=max(tr[x],res); exit; end; m:=(l+r)div 2; if r1<=m then find(x*2,l,m,l1,r1) else if l1>m then find(x*2+1,m+1,r,l1,r1) else begin find(x*2,l,m,l1,m); find(x*2+1,m+1,r,m+1,r1); end; end; begin readln(n,t,m); fillchar(re,sizeof(re),0); fillchar(c,sizeof(c),0); for i:=1 to n do read(a[i]); for i:=1 to n do begin read(b[i]); c[b[i]]:=i; end; for i:=1 to m do read(d[i]); for i:=1 to t do begin read(q[i].l,q[i].r); q[i].id:=i; end; qsort(1,t); s:=1; for i:=1 to t do begin for j:=s to q[i].r do begin for k:=1 to m do begin x:=b[j]+d[k]; if x<=n then y:=c[x]; if (x<=n)and(y<j)and(a[j]+a[y]>re[y])then begin re[y]:=a[j]+a[y]; insert(1,1,n,y,re[y]); end; x:=b[j]-d[k]; if x<0 then continue; y:=c[x]; if (x>=1)and(y<j)and(a[j]+a[y]>re[y])then begin re[y]:=a[j]+a[y]; insert(1,1,n,y,re[y]); end; end; end; res:=0; find(1,1,n,q[i].l,q[i].r); ans[q[i].id]:=res; s:=q[i].r; end; for i:=1 to t do writeln(ans[i]); end.
相关文章推荐