题目链接  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. COMP9021--6.17

    1. ''' '''the comment in the middle will be shown in your code while ranning 2. a=bc=a%bor we can si ...

  2. python输出mssql 查询结果示例

    # -*- coding: utf-8 -*-# python 3.6import pymssql conn=pymssql.connect(host='*****',user='******',pa ...

  3. 虚拟机上的Linux学习

    title: 虚拟机上的Linux学习 date: 2018-08-08 15:48:28 updated: tags: [Linux,学习笔记] description: keywords: com ...

  4. luogu2761 软件补丁问题

    状压最短路 #include <iostream> #include <cstring> #include <cstdio> #include <queue& ...

  5. 4.Vim编辑器与Shell命令脚本

    第4章 Vim编辑器与Shell命令脚本 章节简述: 本章首先讲解如何使用Vim编辑器来编写.修改文档,然后通过逐个配置主机名称.系统网卡以及Yum软件仓库参数文件等实验,帮助读者加深Vim编辑器中诸 ...

  6. oracle无参数和带参数的存储过程实例

    SQL中调用存储过程语句:call procedure_name(); 注:调用时”()”是不可少的,无论是有参数还是无参数. 定义对数据库存储过程的调用时1.无参数存储过程:{call proced ...

  7. 设计模式(八)组合模式 Composite

    组合模式: 允许你将对象组合成树形结构来表现“整体/部分”层次结构.组合能让客户以一致的方式处理个别对象以及对象组合. 组合模式适用于创建复杂的对象,这个对象包含某些个别的对象以及这些对象的组合. 从 ...

  8. 解决在IE6、7中用height来设定SELECT标签高度无效的兼容性问题

    在IE6.7中用height来设定SELECT标签高度是无效的,宽度的话各浏览器设置都是一致的,解决方法就是在select外嵌套两层标签,一层用来遮挡select的默认边框(在IE6.7中设置bord ...

  9. [BZOJ3817]Sum

    [BZOJ3817]Sum 试题描述 给定正整数N,R.求 输入 第一行一个数 T,表示有 T 组测试数据. 接下来 T 行,每行两个正整数 n,r. 输出 输出 T 行,每行一个整数表示答案. 输入 ...

  10. bzoj 1572: [Usaco2009 Open]工作安排Job

    Description Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间. 他的工作日从0时刻开始,有1000000000个单 ...