ZSTU 4241 圣杯战争(ST表+二分)
题目链接 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表+二分)的更多相关文章
- 「ZJOI2018」胖(ST表+二分)
「ZJOI2018」胖(ST表+二分) 不开 \(O_2\) 又没卡过去是种怎么体验... 这可能是 \(ZJOI2018\) 最简单的一题了...我都能 \(A\)... 首先我们发现这个奇怪的图每 ...
- 【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分
4310: 跳蚤 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 180 Solved: 83[Submit][Status][Discuss] De ...
- BZOJ4556 [Tjoi2016&Heoi2016]字符串 SA ST表 二分答案 主席树
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4556.html 题目传送门 - BZOJ4556 题意 给定一个长度为 $n$ 的字符串 $s$ . ...
- hdu5289 ST表+二分
用裸的St表+暴力枚举查询时稳TLE的,可以枚举每个区间的起点+二分满足条件的区间右端,这样复杂度是O(nlogn) #include<iostream> #include<cstr ...
- luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分
仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...
- 2016多校联合训练1 D题GCD (ST表+二分)
暑假颓废了好久啊...重新开始写博客 题目大意:给定10w个数,10w个询问.每次询问一个区间[l,r],求出gcd(a[l],a[l+1],...,a[r])以及有多少个区间[l',r']满足gcd ...
- 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)
题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...
- GCD(st表+二分)
GCD Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...
- Codeforces 713D Animals and Puzzle(二维ST表+二分答案)
题目链接 Animals and Puzzle 题意 给出一个1e3 * 1e3的01矩阵,给出t个询问,每个询问形如x1,y1,x2,y2 你需要回答在以$(x1, y1)$为左上角,$(x1, ...
随机推荐
- Python简单试题3
1,水仙花数 水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身 (例如:1^3 + 5^3+ 3^3 = 153) 代码如下: 方法一: for i in range(100, ...
- python标准输入输出
input() 读取键盘输入 input() 函数从标准输入读入一行文本,默认的标准输入是键盘. input 可以接收一个Python表达式作为输入,并将运算结果返回. print()和format( ...
- 爬虫制作入门学习笔记2:[转]python爬虫实例项目大全
WechatSogou [1]- 微信公众号爬虫.基于搜狗微信搜索的微信公众号爬虫接口,可以扩展成基于搜狗搜索的爬虫,返回结果是列表,每一项均是公众号具体信息字典. DouBanSpider [2]- ...
- oracle如何保证读一致性 第一弹
oracle保证读一致性原理 1:undo segment的概念 当数据库进行修改的时候,需要把保存到以前的old的数据保存到一个地方,然后进行修改,用于保存o ...
- 牛客练习赛29 B
炎热的早上,gal男神们被迫再操场上列队,gal男神们本来想排列成x∗x的正方形,可是因为操场太小了(也可能是gal男神太大了),校长安排gal男神们站成多个4∗4的正方形(gal男神们可以正好分成n ...
- python基础学习笔记——列表及元组
列表 列表的介绍 列表是python的基础数据类型之一 ,其他编程语言也有类似的数据类型. 列表的索引和切片 列表和字符串一样也拥有索引: lst = ['刘德华','周润发','周杰伦','向华强 ...
- matlab callback 数据传递
M文件中内的每个Callback都可以视为一个独立的可执行的接口,因此,任一个Callback触发后所执行的运算值若要在其他Callback中使用,就无法与MATLAB工作空间内的变量继续执行操作,也 ...
- luogu3193 [HNOI2008]GT考试
there #include <iostream> #include <cstdio> using namespace std; int n, m, mod, nxt[25], ...
- Selenium WebDriver- 操作frame中的页面元素
#encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webdriver i ...
- Mysql 安装及MySQL-python 问题
今天遇到了个低级问题: EnvironmentError:mysql_config not found 网上谷歌了一圈发现没用,静下来想的时候才发现新电脑没安装Mysql,吐血 后面再去官网上下载My ...