传送门

想题5分钟调题两小时系列 其实还是我tcl

读完题之后自然会知道一个关键点能够更新的点是一段连续的区间,于是我们对于每个点能到的左右区间二分答案,用ststst表维护一下查询即可。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const int N=2e5+5;
typedef long long ll;
ll s1[N],s2[N],ans;
int mp[N],a[N],n,m,k;
struct pot{int a;ll w;friend inline bool operator<(const pot&a,const pot&b){return a.a<b.a;}}b[N];
struct ST{
	ll st[N][20];
	int Log[N];
	inline void init(){Log[0]=-1;for(ri i=1;i<=n;++i)Log[i]=Log[i>>1]+1;}
	inline void Pre(){
		for(ri i=1;i<=k;++i)st[i][0]=b[i].w;
		for(ri j=1;j<=Log[k];++j)for(ri i=1;i<=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=lower_bound(mp+1,mp+k+1,max(l,1))-mp;
		r=upper_bound(mp+1,mp+k+1,min(r,n))-mp-1;
		if(l>r)return 1e18;
		int k=Log[r-l+1];
		return min(st[l][k],st[r-(1<<k)+1][k]);
	}
}pre,suf;
inline bool check1(int mid,int x){
	if(mid==x)return 1;
	ll d1=pre.query(mid*2-x+1,mid)+s1[mid],d2=suf.query(mid,x-1)-s1[mid],d3=suf.query(x,x)-s1[mid];
	if(d1<=d3||d2<=d3)return 0;
	return mid*2-x>=1?pre.query(mid*2-x,mid*2-x)+s1[mid]>=d3:1;
}
inline bool check2(int x,int mid){
	if(x==mid)return 1;
	ll d1=suf.query(mid,mid*2-x-1)-s1[mid],d2=pre.query(x+1,mid)+s1[mid],d3=pre.query(x,x)+s1[mid];
	if(d1<=d3||d2<=d3)return 0;
	return mid*2-x<=n?suf.query(mid*2-x,mid*2-x)-s1[mid]>d3:1;
}
inline void solve(int id){
	int l=1,r=b[id].a,res1=0,res2=0,mid;
	while(l<=r){if(check1((mid=l+r>>1),b[id].a))r=mid-1,res1=mid;else l=mid+1;}
	l=b[id].a,r=n;
	while(l<=r){if(check2(b[id].a,(mid=l+r>>1)))l=mid+1,res2=mid;else r=mid-1;}
	ans+=res2-res1+1;
}
int main(){
	n=read(),m=read();
	pre.init(),suf.init();
	for(ri i=2;i<=n;++i)s1[i]=s1[i-1]+(a[i]=read());
	while(m--){
		ans=0,k=read();
		for(ri i=1;i<=k;++i)b[i].a=read(),b[i].w=read()-s1[b[i].a];
		sort(b+1,b+k+1);
		for(ri i=1;i<=k;++i)mp[i]=b[i].a;
		pre.Pre();
		for(ri i=1;i<=k;++i)b[i].w+=s1[b[i].a]<<1;
		suf.Pre();
		for(ri i=1;i<=k;++i)solve(i);
		cout<<ans<<'\n';
	}
	return 0;
}

2019.03.04 bzoj5308: [Zjoi2018]胖(二分答案+st表)的更多相关文章

  1. 2018.10.14 NOIP训练 直线(二分答案+st表+切比雪夫距离转化)

    传送门 二分答案好题. 这已经是当年普及组模拟时挖的坑了233. 这道题还是很不错的. 考虑把坐标系转个45度再操作. 为了不爆精度可以直接转切比雪夫距离. 然后就直接二分答案. 其中竖线就按二分的答 ...

  2. bzoj3277 串 (后缀数组+二分答案+ST表)

    常见操作:先把所有串都连到一起,但中间加上一个特殊的符号(不能在原串中/出现过)作为分割 由于全部的子串就等于所有后缀的所有前缀,那我们对于每一个后缀,去求一个最长的前缀,来满足这个前缀在至少K个原串 ...

  3. P7599-[APIO2021]雨林跳跃【二分,倍增,ST表】

    正题 题目链接:https://www.luogu.com.cn/problem/P7599 题目大意 \(n\)棵树,在某棵树上时可以选择向左右两边第一棵比它高的树跳,现在\(q\)次询问从\([A ...

  4. ZJOI2018 胖 二分 ST表

    原文链接https://www.cnblogs.com/zhouzhendong/p/ZJOI2018Day2T2.html 题目传送门 - BZOJ5308 题目传送门 - LOJ2529 题目传送 ...

  5. BZOJ5308 ZJOI2018胖

    贝尔福特曼(?)的方式相当于每次将所有与源点直接相连的点的影响区域向两边各扩展一格.显然每个点在过程中最多更新其他点一次且这些点构成一段连续区间.这个东西二分st表查一下就可以了.注意某一轮中两点都更 ...

  6. 【CSP膜你赛】柠檬的密码(manacher 二分 单调性 st表)

    题目描述 Lemon觉得他需要一个复杂的密码来保证他的帐号的安全.他经过多日思考,决定使用一个长度为奇数的回文串来作为他的密码.  但是这个回文串太长了,Lemon记不住,于是Lemon决定把它记在本 ...

  7. Codeforces 475D 题解(二分查找+ST表)

    题面: 传送门:http://codeforces.com/problemset/problem/475/D Given a sequence of integers a1, -, an and q ...

  8. [BZOJ3277/BZOJ3473] 串 - 后缀数组,二分,双指针,ST表,均摊分析

    [BZOJ3277] 串 Description 现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Solution 首先将所有串连 ...

  9. [多校联考2019(Round 4 T2)][51nod 1288]汽油补给(ST表+单调栈)

    [51nod 1288]汽油补给(ST表+单调栈) 题面 有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的 ...

随机推荐

  1. BasicConverter 基本数据类型转换器

    package cn.ubibi.jettyboot.framework.commons; import com.alibaba.fastjson.JSON; import com.alibaba.f ...

  2. [Unity算法]点是否在多边形范围内

    参考链接: https://www.zhihu.com/question/26551754 http://www.cnblogs.com/leoin2012/p/6425089.html 原理如下: ...

  3. JEECG-Swagger UI的使用说明

    一.代码生成 (此步骤为代码生成器的使用,如不清楚请查阅相关文档视频) 1.进入菜单[在线开发]-->[Online表单开发],选中一张单表/主表,点击代码生成按钮. 2.弹出页面中填写代码生成 ...

  4. Controller层aop

    利用@Around通知修改Controller的返回值 自定义一个注解@OperationBtn 在切入点Controller上加上自定义注解 接下来就是重点了,AspectJ写切面类,对该Contr ...

  5. MQTT协议

    MQTT(Message Queue Telemerty Transport)是一种二进制协议,主要用于服务器和那些低功耗的物联网设备(IoT)之间的通信. 它位于 TCP 协议的上层,除了提供发布- ...

  6. java学习笔记(十):scanner输入

    可以通过 Scanner 类来获取用户的输入. 通过next()类和nextLine()类来获取字符串. 通过 Scanner 类的 next() 类来获取输入的字符串. import java.ut ...

  7. AS3中的单件(Singleton)模式

    单件(singleton)模式在c#中是最容易实现的模式,其主要用意就在于限制使用者用new来创建多个实例.但在as3中,构造函数必须是public的(语法本身要求的),而且也不能在构造函数中抛出异常 ...

  8. 深入JVM之类的加载过程

    类的加载—连接—初始化 加载:查找并加载类的字节码文件,从硬盘到内存. 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.la ...

  9. php的AES加密、解密类

    <?php /** * php.ios.Android 通用的AES加密.解密方法 */ namespace Common\Business; class AESCrypt { /** * 初始 ...

  10. List Set Map的区别

    1.读取频繁选用List 快速访问选取ArrayList,经常进行添加删除工作可以选用LinkList 2.如果你想进行有序的插入那么还是选型List,因为List是一个有序的容器 3.如果你想保证插 ...