[传送门]

写的时候一直没有想到离线解法,反而想到两个比较有趣的解法。
一是分块,$f[i][j]$表示第$i$块块首元素到第$j$个元素之间满足条件的最大值(即对$B_l + B_r \in K$的$A_l + A_r$的最大值)。这个可以$O(nm\sqrt n)$预处理,查询就$l$属于的块$p$得到$f[p+1][r]$和暴力$l$到$min(r,R[p])$的最大值合并一下,但是不知道为啥狂T QAQ,51nod好像没开O2,开O2第一组T的数据跑了1.4s,不开O2跑了5s,难道真是复杂度不对?还是写丑了?很难受。
第二个想法是从“画”样例得来的
对于每一个数$B_i$,可以预处理出$B_j$满足$B_i + a = B_j\left(a \in K\right)$的位置以及对应的$A$之和(只需要往大的方向找即可)
比如样例的
$A$: 1 2 3 4
$B$: 3 2 1 4
$i = 1$:0 0 0 5
$i = 2$:3 0 0 0
$i = 3$:0 5 0 7
$i = 4$:0 0 0 0
那么我要查询$\left[l,r\right]$之间满足条件的最大值,相当于在这个二维矩阵里$RMQ$,比如样例查询$\left[1, 4\right]$就是在矩阵$(1,1)$$(4,4)$里查询其最大值得到$7$,另一个样例在$(2,2)$$(3,3)$里查询得到$5$,那么就可以动态开点二维线段树$RMQ$,复杂度应该是$O(nlog^2n)$。至此,我已经不想写了。
看了题解发现可以离线加扫描线处理,就是把所有询问按右端点排序,新加入一个点就枚举这个点所有符合的元素的位置,如果位置在当前扫描线之前,就可以把它们的$A$之和加到对应位置上,如果比原位置的值大则更新。而扫描线用来扫右端点,未到下一个右端点则更新,到了直接查询当前线段树上的$[l,r]$区间。
其实这个本质就是二维矩阵$RMQ$,因为不带修改,那么可以通过扫描线来减少一维。终于懂了QAQ

#include <bits/stdc++.h>
#define ll long long
using namespace std; const int N = 1e5 + ; struct Seg {
#define lp p << 1
#define rp p << 1 | 1
ll tree[N << ];
inline void pushup(int p) {
tree[p] = max(tree[lp], tree[rp]);
}
void update(int p, int l, int r, int pos, ll val) {
if (l == r) {
tree[p] = max(tree[p], val);
return;
}
int mid = l + r >> ;
if (pos <= mid) update(lp, l, mid, pos, val);
else update(rp, mid + , r, pos, val);
pushup(p);
}
ll query(int p, int l, int r, int x, int y) {
if (x <= l && y >= r) return tree[p];
int mid = l + r >> ;
ll ans = ;
if (x <= mid) ans = max(ans, query(lp, l, mid, x, y));
if (y > mid) ans = max(ans, query(rp, mid + , r, x, y));
return ans;
}
} seg; struct Query {
int l, r, id;
inline bool operator < (const Query &rhs) const {
return r < rhs.r;
}
} query[N]; ll a[N], ans[N];
int b[N], k[N], pos[N]; int main() {
int n, q, m;
scanf("%d%d%d", &n, &q, &m);
for (int i = ; i <= n; i++)
scanf("%lld", &a[i]);
for (int i = ; i <= n; i++)
scanf("%d", &b[i]), pos[b[i]] = i;
for (int i = ; i <= m; i++)
scanf("%d", &k[i]);
for (int i = ; i <= q; i++)
scanf("%d%d", &query[i].l, &query[i].r), query[i].id = i;
sort(query + , query + + q);
int now = ;
for (int i = ; i <= q; i++) {
while (now < query[i].r) {
now++;
ll mx = ;
for (int j = ; j <= m; j++) {
int temp = b[now] - k[j];
if (temp > && temp <= n && pos[temp] < now) seg.update(, , n, pos[temp], a[now] + a[pos[temp]]);
temp = b[now] + k[j];
if (temp <= n && temp > && pos[temp] < now) seg.update(, , n, pos[temp], a[now] + a[pos[temp]]);
}
}
ans[query[i].id] = seg.query(, , n, query[i].l, query[i].r);
}
for (int i = ; i <= q; i++)
printf("%lld\n", ans[i]);
return ;
}

51nod1463 找朋友的更多相关文章

  1. 51nod 1463 找朋友 (扫描线+线段树)

    1463 找朋友  基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80 难度:5级算法题  收藏  关注 给定: 两个长度为n的数列A .B 一个有m个元素的集合K 询问Q次 每次询 ...

  2. hunnu--11548--找啊找啊找朋友

    找啊找啊找朋友 Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 14,  ...

  3. 【BZOJ4264】小C找朋友 随机化

    [BZOJ4264]小C找朋友 Description 幼儿园里有N个小C,两个小C之间可能是朋友也可能不是.所有小C之间的朋友关系构成了一个无向图,这个无向图中有M条边. 园长ATM发现对于两个(不 ...

  4. Java程序设计——反转字符串 & 找朋友 & 计算int型二进制1的个数 & 情报加密 & 计算日期 & 求近似数 & 输出较小数(练习1)

    作为刚刚入门Java的选手,其实C++的功底起到了很大的作用.但是,Java之于C++最大的不同,我个人认为,是其类的多样性.才入门的我,写着老师布置的简单的面对过程的题,如果是C++,可以算是简单了 ...

  5. 懒羊羊找朋友(struct实现优先排序)

    4907: 懒羊羊找朋友(点击) 时间限制: 1 Sec  内存限制: 128 MB                                                           ...

  6. 刷题总结——小c找朋友(bzoj4264 集合hash)

    题目: Description 幼儿园里有N个小C,两个小C之间可能是朋友也可能不是.所有小C之间的朋友关系构成了一个无向图,这个无向图中有M条边. 园长ATM发现对于两个(不同的)小Ci和j,如果其 ...

  7. TYVJ P1082 找朋友 Label:字符串

    描述 童年的我们,对各种事物充满了好奇与向往.这天,小朋友们对数字产生了兴趣,并且想和数字交朋友.可是,怎么分配这些数字才能使得每个小朋友都唯一地找到一个数字朋友呢?C小朋友说:咱们按自己名字的字典序 ...

  8. P1082 找朋友

    描述 童年的我们,对各种事物充满了好奇与向往.这天,小朋友们对数字产生了兴趣,并且想和数字交朋友.可是,怎么分配这些数字才能使得每个小朋友都唯一地找到一个数字朋友呢?C小朋友说:咱们按自己名字的字典序 ...

  9. BZOJ 4264 小C找朋友 哈希+脑子

    好吧我觉得是脑子,别人觉得是套路$qwq$ 这道题相当于是求除了$u,v$两点互相连接,所连的点相同的点对$(u,v)$ 我们首先每个点一个随机权值,对于$u$点记为$w[u]$,然后记与$u$点相连 ...

随机推荐

  1. Java开发笔记(一百四十七)通过JDBC管理数据库

    前面介绍了如何通过JDBC获取数据库连接,可是Connection对象不能直接执行SQL语句,需要引入Statement报告对象才能操作SQL.Statement对象由Connection的creat ...

  2. 常用SQL指令

    SQL去重复语句:select 改为Delete select * from TRWTC01 where ITEM_NAME in (select ITEM_NAME from TRWTC01 gro ...

  3. c,使用lib,dll

    lib使用: #include "xxx.h" // lib的头文件 #pragma comment(lib, "xxx.lib") 这样会将lib里的数据编译 ...

  4. ETCD服务

    ETCD 简介 ETCD是一个开源的.分布式的键值对数据存储系统,由Go语言实现,用于存储key-value键值对,同时不仅仅是存储,主要用途是提供共享配置及服务发现,使用Raft一致性算法来管理高度 ...

  5. windwos源码安装mysql

    进入官网下载相关的mysql安装文件,解压到指定目录如E:\mysql-5.7.23-winx64下,然后进入该目录下新建data文件夹与my.ini文件,在my.ini文件中 [mysqld] po ...

  6. react-router的BrowserHistory 和 HashHistory 的区别,如何解决使用BrowserHistory 引起的访问路径问题

    一,使用createBrowserHistory 和 createHashHistory 的 区别体现 1. 使用createBrowserHistory () // 使用createBrowserH ...

  7. java之spring mvc之Controller配置的几种方式

    这篇主要讲解 controller配置的几种方式. 1. URL对应 Bean 如果要使用此类配置方式,需要在XML中做如下样式配置 <!-- 配置handlerMapping --> & ...

  8. C# 调用 C++ dll的两种方式

    目录: 1.非托管方式 2.托管方式 3.介绍 extern "C" 4.介绍   DllImport 1.非托管方式 第一种,非托管方式:调用类和方法https://www.co ...

  9. 2019 快乐阳光java面试笔试题 (含面试题解析)

    本人3年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.快乐阳光等公司offer,岗位是Java后端开发,最终选择去了快乐阳光. 面试了很多家公司,感觉大部分公司考察的点 ...

  10. 拓展 - Webrtc 的回声抵消(aec、aecm)算法简介

    webrtc 的回声抵消(aec.aecm)算法简介 原文链接:丢失.不好意思        webrtc 的回声抵消(aec.aecm)算法主要包括以下几个重要模块:1.回声时延估计 2.NLMS( ...