题目链接  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. UVa - 1593 代码对齐(STL)

    看上去十分麻烦的一道题,但是看了看别人的写法感觉大神们写的无比简单. 就是记一个每列单词的最大长度,然后剩下的事交给NB的iomanip头文件就好. stringsteam是一个神奇的东西. #inc ...

  2. cf 1020 C

    C. Elections time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  3. poj 1328 安雷达问题 贪心算法

    题意:雷达如何放置?在xoy二维平面坐标系里面,x轴上方的为岛屿,x轴下方的是雷达要放到位置,如何放使得雷达放的最少? 思路 肯定放在x轴上减少浪费是最好的选择 什么情况下,雷达无法到达呢?--以这个 ...

  4. debian软raid

    http://www.linuxidc.com/Linux/2013-06/86487.htm  

  5. LayaAir环境TypeScript

    1.1 Node.js下载 ​ TypeScript开发HTML5需要Node.js环境,如果没有安装过的,请前往官方下载(建议LTS版本),如图1,URL地址为:https://nodejs.org ...

  6. python偏函数使用

    偏函数依托于python functools模块.

  7. .NET开发时让人头痛的SESSION超时

    前言 不知道大家在使用用.NET的SESSION的时候有没有遇到过很奇怪的问题,不时候不知道怎么回事,这个SESSION就无缘无故的丢失了 怎么也想不通,不是说SESSION很可靠的吗?这个问题要好好 ...

  8. LinearLayout 滚动条

    比如文件列表, 显示不下,需要出滚动条:外面加一个scrollview 直接上代码: <?xml version="1.0" encoding="utf-8&quo ...

  9. Conda相关命令的使用

    -- Conda basics Conda基础命令 conda info 查看已安装的环境 conda install PACKAGENNAME 安装包 conda update PACKAGENAM ...

  10. 九度oj 题目1527:首尾相连数组的最大子数组和

    题目描述: 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首尾是相连的.数组中一个或多个连续元素可以组成一个子数组,其中存在这样的子数组arr[i],…arr ...