「ZJOI2018」胖(ST表+二分)
「ZJOI2018」胖(ST表+二分)
不开 \(O_2\) 又没卡过去是种怎么体验。。。
这可能是 \(ZJOI2018\) 最简单的一题了。。。我都能 \(A\)。。。
首先我们发现这个奇怪的图每个点扩展的是一个区间 \([L,R]\),然后我们就可以二分端点了。
一个点 \(x\) 扩展到点 \(y\) 至少要 \(|x-y|\) 的时间,所以我们把 \(a_i\) 排个序,在上面二分一个合法的区间使得 \(|x-a_l|\leq t\) 且 \(|x-a_r|\leq t\)
然后若能扩展到 \(y\),那么 \(0\) 号点到 \(y\) 号点的距离为 \(|dis_y-dis_x|+l\)。我们用两个 \(ST\) 表把绝对值拆掉,分别维护最小值即可。
时间复杂度 \(O(n\log^2 n)\)
为什么 \(dl\) 出题人会出到 \(2\times 10^5\)。。。两个 \(\log\) 一般只出到 \(10^5\) 的啊。。。
\(Code\ Below:\)
// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=200000+10;
int n,m,k,w[maxn],lg[maxn];ll dis[maxn];
struct node{
int p;ll l;
node(int p=0,ll l=0):p(p),l(l){}
}a[maxn];
inline bool operator < (const node &a,const node &b){
return a.p<b.p;
}
struct Sparse_Table{
ll st[maxn][18];
inline void init(){
for(int i=1;i<=k;i++) st[i][0]=a[i].l;
for(int j=1;j<=lg[k];j++)
for(int i=1;i+(1<<j)-1<=k;i++) st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
inline ll query(int l,int r){
l=max(l,1);r=min(r,n);
l=lower_bound(a+1,a+k+1,node(l))-a;
r=upper_bound(a+1,a+k+1,node(r))-a-1;
if(l>r) return 1e18;
int k=lg[r-l+1];
return min(st[l][k],st[r-(1<<k)+1][k]);
}
}L,R;
inline int read(){
register int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return (f==1)?x:-x;
}
inline bool check1(int x,int y){
// (2*y-x,y,x]
if(x==y) return 1;
ll a=L.query(2*y-x+1,y)+dis[y];
ll b=R.query(y,x-1)-dis[y];
ll c=R.query(x,x)-dis[y];
if(a<=c||b<=c) return 0;
if(2*y-x>=1) return L.query(2*y-x,2*y-x)+dis[y]>=c;
return 1;
}
inline bool check2(int x,int y){
// [x,y,2*y-x)
if(x==y) return 1;
ll a=L.query(x+1,y)+dis[y];
ll b=R.query(y,2*y-x-1)-dis[y];
ll c=L.query(x,x)+dis[y];
if(a<=c||b<=c) return 0;
if(2*y-x<=n) return R.query(2*y-x,2*y-x)-dis[y]>c;
return 1;
}
inline int solve1(int x){
int l=1,r=x,mid,ans=0;
while(l<=r){
mid=(l+r)>>1;
if(check1(x,mid)) r=mid-1,ans=mid;
else l=mid+1;
}
return ans;
}
inline int solve2(int x){
int l=x,r=n,mid,ans=0;
while(l<=r){
mid=(l+r)>>1;
if(check2(x,mid)) l=mid+1,ans=mid;
else r=mid-1;
}
return ans;
}
int main()
{
n=read(),m=read();
for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
for(int i=2;i<=n;i++){
w[i]=read();
dis[i]=dis[i-1]+w[i];
}
ll ans;
while(m--){
k=read();
for(int i=1;i<=k;i++) a[i].p=read(),a[i].l=read();
sort(a+1,a+k+1);ans=0;
for(int i=1;i<=k;i++) a[i].l-=dis[a[i].p];L.init();
for(int i=1;i<=k;i++) a[i].l+=2*dis[a[i].p];R.init();
for(int i=1;i<=k;i++) ans+=solve2(a[i].p)-solve1(a[i].p)+1;
printf("%lld\n",ans);
}
return 0;
}
「ZJOI2018」胖(ST表+二分)的更多相关文章
- Loj #2529. 「ZJOI2018」胖
Loj #2529. 「ZJOI2018」胖 题目描述 Cedyks 是九条可怜的好朋友(可能这场比赛公开以后就不是了),也是这题的主人公. Cedyks 是一个富有的男孩子.他住在著名的 The P ...
- 「ZJOI2018」历史
「ZJOI2018」历史 前置知识 \(\text{LCT}\) 维护子树信息,考虑辅助树上一个节点的子树信息只是其代表的这一段链的信息,设 \(S(u)\) 为节点 \(u\) 的子树信息,那么在辅 ...
- 「ZJOI2018」历史(LCT)
「ZJOI2018」历史(LCT) \(ZJOI\) 也就数据结构可做了-- 题意:给定每个点 \(access\) 次数,使轻重链切换次数最大,带修改. \(30pts:\) 挺好想的.发现切换次数 ...
- 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)
题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...
- 【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 ...
随机推荐
- python 在window 系统 连接并操作远程 oracle 数据库
1,python 连接 oracle 需要 oracle 自身的客户端 instantclient,可以去官网下载自己需要的版本, https://www.oracle.com/technetwor ...
- leetcode617
这道题想了很久,并没有掌握思想,写了很多,也没有解决.先贴出思考的过程. class Solution { public: vector<TreeNode> v1; vector<T ...
- IIC 设备使用
通过 读 / 写 IIC 设备上特定的存储空间,来使用设备提供的功能: 存储空间地址 = 设备名 + 设备地址(Slave Address) + 寄存器地址 . 注:设备地址.寄存器地址.地址中写入数 ...
- EF 6.x实现dynamic动态查询
利用SqlQuery实现动态查询 public static IEnumerable<dynamic> SqlQueryDynamic(this DbContext db, string ...
- 【395】yield 和 yield from
yield:生成器 yield from:将生成器 yield 的内容相当于逐一在 yield 一般 参考:Python 3: Using "yield from" in Gene ...
- vue浏览器滚动加载更多
created () { var that = this; window.addEventListener('scroll',this.scroll,true) console.log(this.$r ...
- 在windows下安装Git并用GitHub同步
准备环境: 1,注册github账户 2,下载安装git(下载地址:https://git-scm.com/download/win) 注释: git是什么? git是版本管理工具,当然也是分布式的管 ...
- python--第十一天总结(paramiko 及数据库操作)
堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 实现思路 堡垒机执行流程: 管理员为用户在服务器上创建账号(将公钥放置服务器, ...
- 如何强制停止http请求
http请求很多时候会受到网络阻塞.重连等原因导致响应很慢,如果此时做了一些操作,但过几秒后又响应了之前的请求,就会造成很多问题,此时我们可以使用abort()方法强制停止http请求: let aj ...
- 计算a月的第b个星期c
计算从y1到y2年a月的第b个星期c的日期 #include<iostream> using namespace std; bool isLeap(int y) { == || y%==& ...