题目

P4501 [ZJOI2018]胖

官方口中的送分题

做法

我们通过手玩(脑补),\(a_i\)所作的贡献(能更新的点)为:在\(a_i\)更新\(\forall x\)更新前前没有其他点能把\(x\)更新到更优

我们预处理出数组\(dis[i]\)为\(1\)号点走到\(i\)号点的未包含计划前的距离

对于\(x≤a[i]\Longrightarrow edge[x]=-dis[x]+(l[i]+dis[a[i]])\),对于\(x≥a[i]\Longrightarrow dis[x]+(l[i]-dis[a[i]])\)

能更新的范围显然是有单调性的,二分左右端点(\(st\)表维护区间最小值判断),时间复杂度\(O(nlogn^2)\)

My complete code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL maxn=1e6,inf=1e17;
inline LL Read(){
LL x(0),f(1);char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
return x*f;
}
LL n,q,K; LL dis[maxn];
struct node{
LL p,l;
bool operator < (const node &b)const{
return p<b.p;
}
}a[maxn];
struct ST{
LL st1[maxn][20],st2[maxn][20];
inline void Init(){
for(LL i=1;i<=K;++i)
st1[i][0]=a[i].l-dis[a[i].p],st2[i][0]=a[i].l+dis[a[i].p];
for(LL j=1;j<=18;++j)
for(LL i=1;i<=K;++i)
st1[i][j]=min(st1[i][j-1],st1[i+(1<<j-1)][j-1]),
st2[i][j]=min(st2[i][j-1],st2[i+(1<<j-1)][j-1]);
}
inline LL Getl(LL x){
node tmp; tmp.p=x;
return lower_bound(a+1,a+1+K,tmp)-a;
}
inline LL Getr(LL x){
node tmp; tmp.p=x;
return upper_bound(a+1,a+1+K,tmp)-a-1;
}
inline LL Query1(LL l,LL r){
if(l>r) swap(l,r); l=max(1ll,l),r=min(n,r);
l=Getl(l),r=Getr(r);
if(l>r) return inf;
LL lg=log2(r-l+1);
return min(st1[l][lg],st1[r-(1<<lg)+1][lg]);
}
inline LL Query2(LL l,LL r){
if(l>r) swap(l,r); l=max(1ll,l),r=min(n,r);
l=Getl(l),r=Getr(r);
if(l>r) return inf;
LL lg=log2(r-l+1);
return min(st2[l][lg],st2[r-(1<<lg)+1][lg]);
}
}ST;
inline bool Check1(LL p,LL x){
if(!(p^x)) return true;
LL lt=ST.Query1(2*x-p+1,x)+dis[x];
LL rt=ST.Query2(x,p-1)-dis[x];
LL now=ST.Query2(p,p)-dis[x];
if(lt<=now||rt<=now) return false;
if(2*x-p>=1) return ST.Query1(2*x-p,2*x-p)+dis[x]>=now;
return true;
}
inline bool Check2(LL p,LL x){
if(!(p^x)) return true;
LL lt=ST.Query1(p+1,x)+dis[x];
LL rt=ST.Query2(x,2*x-p-1)-dis[x];
LL now=ST.Query1(p,p)+dis[x];
if(lt<=now||rt<=now) return false;
if(2*x-p<=n) return ST.Query2(2*x-p,2*x-p)-dis[x]>now;
return true;
}
inline LL Solve1(LL p){
LL l(1),r(p),ret(p);
while(l<=r){
LL mid(l+r>>1);
if(Check1(p,mid)) r=mid-1,ret=mid;
else l=mid+1;
}return ret;
}
inline LL Solve2(LL p){
LL l(p),r(n),ret(p);
while(l<=r){
LL mid(l+r>>1);
if(Check2(p,mid)) l=mid+1,ret=mid;
else r=mid-1;
}return ret;
}
int main(){
n=Read(),q=Read();
for(LL i=2;i<=n;++i)
dis[i]=dis[i-1]+Read();
while(q--){
K=Read();
for(LL i=1;i<=K;++i) a[i]=(node){Read(),Read()};
sort(a+1,a+1+K);
ST.Init();
LL ret(0);
for(LL i=1;i<=K;++i) ret+=(Solve2(a[i].p)-Solve1(a[i].p)+1);
printf("%lld\n",ret);
}return 0;
}

P4501 [ZJOI2018]胖的更多相关文章

  1. 【BZOJ5308】[ZJOI2018]胖(模拟,ST表,二分)

    [BZOJ5308][ZJOI2018]胖(模拟,ST表,二分) 题面 BZOJ 洛谷 题解 首先发现每条\(0\)出发的边都一定会更新到底下的一段区间的点. 考虑存在一条\(0\rightarrow ...

  2. 5308: [Zjoi2018]胖

    5308: [Zjoi2018]胖 链接 分析: 题目转化为一个点可以更新多少个点,一个点可以更新的点一定是一个区间,考虑二分左右端点确定这个区间. 设当前点是x,向右二分一个点y,如果x可以更新到y ...

  3. 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)

    题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...

  4. ZJOI2018 胖 二分 ST表

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

  5. [ZJOI2018]胖

    嘟嘟嘟 都说这题是送分题,但我怎么就不觉得的呢. 看来我还是太弱了啊-- 大体思路就是对于每一个设计方案,答案就是每一个关键点能更新的点的数量之和. 关键在于怎么求一个关键点能更新那些点. 首先这些点 ...

  6. zjoi[ZJOI2018]胖

    题解: 因为n,m很大 所以复杂度应该是和m相关的 考虑到每个点的影响区间是连续的 就很简单了 区间查询最小值线段树维护(st表也可以) 然后注意一下不要重复算一个就可以了 max函数用templat ...

  7. 2019.03.04 bzoj5308: [Zjoi2018]胖(二分答案+st表)

    传送门 想题5分钟调题两小时系列 其实还是我tcl 读完题之后自然会知道一个关键点能够更新的点是一段连续的区间,于是我们对于每个点能到的左右区间二分答案,用ststst表维护一下查询即可. 代码: # ...

  8. BZOJ5308 ZJOI2018胖

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

  9. bzoj 5308: [Zjoi2018]胖

    Description Cedyks是九条可怜的好朋友(可能这场比赛公开以后就不是了),也是这题的主人公. Cedyks是一个富有的男孩子.他住在著名的ThePLace(宫殿)中. Cedyks是一个 ...

随机推荐

  1. Mybatis学习手记(一)

    年近不惑,为生活所迫,重新开始学习JAVA,计划将公司的开发平台统一到JAVA上来.现公司的技术杂乱,有PB开发的程序要维护.有PYTHON的程序要维护,有.NET的,也有JAVA的,非常不容易形成合 ...

  2. MFC多国语言——配置文件

    前段时间,因工作需要,本地化了一个英文版本的产品. 在网上查阅了若干资料,在此进行一个简单的整理. 在MFC程序中,实现多国语言的方式很多,我们选择的是使用配置文件的方法. 在通过配置文件方式实现多国 ...

  3. json responseJson

    private void doResoponseJson(HttpServletResponse resp,String jsonString){ Trace.logError(Trace.COMPO ...

  4. Uva1025 A Spy in the Metro

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; ]; ] ...

  5. yii2 刷新缓存(刷新模型缓存)

    Yii2开启表结构缓存,因为当运用模型(model)时,AR的一些公共属性都会从DB中获取,这样会导致服务器负担一些额外的资源开销,实际上对于成品来说,服务器这些开始销是多余的,故应该阻止这种默认行为 ...

  6. node.js中的路由(url)初步

    1.建立n4_root.js var http = require('http'); var url = require('url'); //这是node.js中自带的var router = req ...

  7. 【BZOJ3638】Cf172 k-Maximum Subsequence Sum 线段树区间合并(模拟费用流)

    [BZOJ3638]Cf172 k-Maximum Subsequence Sum Description 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交 ...

  8. Xamarin.Forms学习之Page Navigation(一)

    在最初接触Xamarin.Forms的时候,我是跟着Xamarin官方的名为“learning-xamarin-ebook”的pdf文档进行学习的,我在成功运行Hello world程序之后,我开始跟 ...

  9. 洛谷 P2523 [HAOI2011]Problem c

    洛谷1或洛谷2,它们是一样的题目,手动滑稽- 这一题我是想不出来, 但是我想吐槽一下坐我左边的大佬. 大佬做题的时候,只是想了几分钟,拍了拍大腿,干脆的道:"这不是很显然吗!" 然 ...

  10. MySQL二进制包安装简略过程

    l  软件目录 [root@MASTER_03 ~]# mkdir -pv /data/software [root@MASTER_03 ~]# cd /data/software/ [root@MA ...