题目链接  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. webpack4搭建Vue开发环境笔记~~持续更新

    项目git地址 一.node知识 __dirname: 获取当前文件所在路径,等同于path.dirname(__filename) console.log(__dirname); // Prints ...

  2. Thinkphp 5 调试执行的SQL语句

    在模型操作中 ,为了更好的查明错误,经常需要查看下最近使用的SQL语句,我们可以用getLastsql方法来输出上次执行的sql语句.例如: User::get(1); echo User::getL ...

  3. Python中的字典与集合

    今天我们来讲一讲python中的字典与集合 Dictionary:字典 Set:集合 字典的语法: Dictionary字典(键值对) 语法: dictionary = {key:value,key: ...

  4. day24 02 单继承(派生)

    day24 02 单继承(派生) 1.首先来看一个简单的例子 比如: 狗类的属性有:吃,喝,看门 鸟类的属性有:吃,喝,下蛋 看门和下蛋就是这两种动物不同的属性,而吃喝是两个共同的属性 以下代码实现了 ...

  5. 【实验吧】编程循环&&求底运算

    要好好学写脚本!!! 循环: 题目介绍 给出一个循环公式,对于一个整数n,当n为奇数时,n=3n+1,当n为偶数时,n=n/2,如此循环下去直到n=1时停止. 现要求对两个整数i = 900.j = ...

  6. Ubuntu 15 下 Qt 配置mysql链接及基本操作

    序 最近需要在Linux下做一个unix网络编程项目,选择了Ubuntu 最新版本15.04 : 开发环境:Qt 5 数据库: MySQL 安装Qt 和 MySQL 简要介绍一下软件的安装! 安装Qt ...

  7. adb -a server nodaemon,设备一直显示 offline,而 adb devices 一直显示 device【已解决】

    1. adb -a server nodaemon 一直显示 offline 2. adb devices 一直显示 device 谷歌 和 度娘了一圈,未寻得解决办法 # 解决方法 问题已解决,使用 ...

  8. 面向对象——property

    1.property特性 property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值 将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉到name是执行了一 ...

  9. [python][oldboy][dict] 遍历字典

    # coding=utf8 dict_info = {"abc": 1, 1: "liuzhipeng"} for k, v in dict_info.item ...

  10. “玲珑杯”线上赛 Round #17 河南专场

    闲来无事呆在寝室打打题,没有想到还有中奖这种操作,超开心的 玲珑杯”线上赛 Round #17 河南专场 Start Time:2017-06-24 12:00:00 End Time:2017-06 ...