题目链接  ZSTU 4241

问题转化为有很多区间,现在每次给定一个区间求这个区间和之前所有区间中的某一个的交集的最大长度。

强制在线。

首先我们把所有的区间预处理出来。

然后去重(那些被包含的小区间可以去掉),再根据左端点升序排序。

这样的话这些区间的右端点也是严格升序的。

现在对于给定的$[x, y]$

所有区间大概可以分成三类。

$1$、左端点落在$[1, x - 1]$,对于这类区间查询右端点最大值即可。

$2$、右端点落在$[y + 1, n]$,对于这类区间查询左端点最小值即可。

$3$、除了上面两种的其他区间,对于这类区间查询区间长度最大值即可。

$1$、$2$直接利用单调性,二分找到满足条件的位置即可。

$3$的话……我选择了$ST$表。

最后答案不能超过给定区间的长度。

时间复杂度$O(nlogn)$

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 2e5 + 10; struct node{
int x, y;
friend bool operator < (const node &a, const node &b){
return a.x == b.x ? a.y > b.y : a.x < b.x;
}
} b[N], c[N]; LL a[N], s[N], p[N];
int pos[N];
int n, m, q;
int T;
int num, cnt, ans;
int f[N][22];
int lg[N]; inline LL calc(int l, int r){ return s[r] - s[l - 1]; } inline int solve(int l, int r){
if (l > r) return 0;
int k = lg[r - l + 1];
return max(f[l][k], f[r - (1 << k) + 1][k]);
} void work(){
rep(i, 1, cnt) f[i][0] = c[i].y - c[i].x + 1;
rep(j, 1, 20) rep(i, 1, cnt)
if ((i + (1 << j) - 1) <= cnt) f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
} int main(){ lg[1] = 0; rep(i, 2, 2e5) lg[i] = lg[i >> 1] + 1; scanf("%d", &T);
while (T--){
scanf("%d%d%d", &n, &m, &q);
rep(i, 1, n) scanf("%lld", a + i);
s[0] = 0;
rep(i, 1, n) s[i] = s[i - 1] + a[i];
rep(i, 1, m) scanf("%d", pos + i);
rep(i, 1, m) scanf("%lld", p + i);
num = 0;
rep(i, 1, m){
if (p[i] < a[pos[i]]) continue;
int l = pos[i], r = n;
while (l + 1 < r){
int mid = (l + r) >> 1;
if (calc(pos[i], mid) <= p[i]) l = mid;
else r = mid - 1;
} int t;
if (calc(pos[i], r) <= p[i]) t = r; else t = l;
++num;
b[num].x = pos[i], b[num].y = t;
} rep(i, 1, m){
if (p[i] < a[pos[i]]) continue;
int l = 1, r = pos[i];
while (l + 1 < r){
int mid = (l + r) >> 1;
if (calc(mid, pos[i]) <= p[i]) r = mid;
else l = mid + 1;
} int t;
if (calc(l, pos[i]) <= p[i]) t = l; else t = r;
++num;
b[num].x = t, b[num].y = pos[i];
} sort(b + 1, b + num + 1);
cnt = 0;
for (int i = 1, j; i <= num; ){
j = i + 1;
while (j <= num && b[j].y <= b[i].y) ++j;
c[++cnt] = b[i];
i = j;
} memset(f, 0, sizeof f);
work(); ans = 0;
while (q--){
int x, y;
scanf("%d%d", &x, &y);
x ^= ans;
y ^= ans;
if (x > y) swap(x, y); ans = 0;
int X, Y;
if (c[1].x >= x) X = 1;
else{
int l = 1, r = cnt;
while (l + 1 < r){
int mid = (l + r) >> 1;
if (c[mid].x < x) l = mid; else r = mid - 1;
} if (c[r].x < x){ X = r + 1; ans = max(ans, c[r].y - x + 1);}
else{ X = l + 1; ans = max(ans, c[l].y - x + 1);}
} if (c[cnt].y <= y) Y = cnt;
else{
int l = 1, r = cnt;
while (l + 1 < r){
int mid = (l + r) >> 1;
if (c[mid].y > y) r = mid; else l = mid + 1;
} if (c[l].y > y){ Y = l - 1; ans = max(ans, y - c[l].x + 1);}
else{ Y = r - 1; ans = max(ans, y - c[r].x + 1); }
} ans = max(ans, solve(X, Y));
ans = min(ans, y - x + 1);
printf("%d\n", ans);
}
} return 0;
}

  

ZSTU 4241 圣杯战争(ST表+二分)的更多相关文章

  1. 「ZJOI2018」胖(ST表+二分)

    「ZJOI2018」胖(ST表+二分) 不开 \(O_2\) 又没卡过去是种怎么体验... 这可能是 \(ZJOI2018\) 最简单的一题了...我都能 \(A\)... 首先我们发现这个奇怪的图每 ...

  2. 【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分

    4310: 跳蚤 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 180  Solved: 83[Submit][Status][Discuss] De ...

  3. BZOJ4556 [Tjoi2016&Heoi2016]字符串 SA ST表 二分答案 主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4556.html 题目传送门 - BZOJ4556 题意 给定一个长度为 $n$ 的字符串 $s$ . ...

  4. hdu5289 ST表+二分

    用裸的St表+暴力枚举查询时稳TLE的,可以枚举每个区间的起点+二分满足条件的区间右端,这样复杂度是O(nlogn) #include<iostream> #include<cstr ...

  5. luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分

    仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...

  6. 2016多校联合训练1 D题GCD (ST表+二分)

    暑假颓废了好久啊...重新开始写博客 题目大意:给定10w个数,10w个询问.每次询问一个区间[l,r],求出gcd(a[l],a[l+1],...,a[r])以及有多少个区间[l',r']满足gcd ...

  7. 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)

    题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...

  8. GCD(st表+二分)

    GCD Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submis ...

  9. Codeforces 713D Animals and Puzzle(二维ST表+二分答案)

    题目链接 Animals and Puzzle 题意  给出一个1e3 * 1e3的01矩阵,给出t个询问,每个询问形如x1,y1,x2,y2 你需要回答在以$(x1, y1)$为左上角,$(x1, ...

随机推荐

  1. PHP 代码优化建议

    1.尽量静态化: 如果一个方法能被静态,那就声明它为静态的,速度可提高1/4,甚至我测试的时候,这个提高了近三倍.当然了,这个测试方法需要在十万级以上次执行,效果才明显.其实静态方法和非静态方法的效率 ...

  2. 用Comparator排序和分组

    Test实体 import java.util.Objects; /** * @author gallen * @description * @date 2018/11/16 * @time 18:5 ...

  3. 利用PowerDesigner逆向工程导出PDM模型及生成文档

    原文:利用PowerDesigner逆向工程导出PDM模型及生成文档 最近需要对老项目进行重构优化,由于项目都是好几年前的,相关设计资料很不全,最基本的数据库设计文档都没有,只能利用PowerDesi ...

  4. python字符串、列表和字典的说明

    python字符串.列表和字典的说明 字符串.列表.字典 字符串的作用存储一段数据信息.例如 info = '我爱北京天安门' ,在调取的时候可以直接调取,灵活方便,print(info) 就可以把刚 ...

  5. CodeForces 570D DFS序 树状数组 Tree Requests

    参考九野巨巨的博客. 查询一个子树内的信息,可以通过DFS序转成线形的,从而用数据结构来维护. #include <iostream> #include <cstdio> #i ...

  6. 光学字符识别OCR-6 光学识别

    经过前面的文字定位和文本切割,我们已经能够找出图像中单个文字的区域,接下来可以建立相应的模型对单字进行识别. 模型选择         在模型方面,我们选择了深度学习中的卷积神经网络模型,通过多层卷积 ...

  7. executing an update/delete query问题

    是因为在做SpringDataJpa更新和删除操作的时候Repository层没有加事务的注解,加上就行了: @Transactional @Query(value = "update ms ...

  8. /mnt/sdcard 是什么东西

    关于/mnt/sdcard和sdcard的区别,可以这样理解:其实,安卓系统是从Linux而衍生出来的,而mnt是unix/Linux传统系统下挂载外部设备的专用目录,Linux默认挂载外部设备都会挂 ...

  9. 山东理工大学第七届ACM校赛-G 飞花的传送门

    G - 飞花的传送门 飞花壕最近手头比较宽裕,所以想买两个传送门来代步(夏天太热,实在是懒得走路).平面上有N个传送门,飞花壕想要挑两个距离最远的传送门带回家(距离为欧几里得距离,即两点之间直线距离) ...

  10. 【转】深入理解JVM—JVM内存模型

    http://www.cnblogs.com/dingyingsi/p/3760447.html#3497199 我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU ...