Description

Cedyks是九条可怜的好朋友(可能这场比赛公开以后就不是了),也是这题的主人公。
Cedyks是一个富有的男孩子。他住在著名的ThePLace(宫殿)中。
Cedyks是一个努力的男孩子。他每天都做着不一样的题来锻炼他的The SaLt(灵魂)。
这天,他打算在他的宫殿外围修筑一道城墙,城墙上有n座瞭望塔。
你可以把城墙看做一条线段,瞭望塔是线段上的n个点,其中1和n分别为城墙的两个端点。
其中第i座瞭望塔和第i+1座瞭望塔的距离为wi,他们之间的道路是双向的。
城墙很快就修建好了,现在Cedyks开始计划修筑他的宫殿到城墙的道路。
因为这题的题目名称,
Cedyks打算用他的宫殿到每一个瞭望塔的最短道路之和来衡量一个修建计划。
现在Cedyks手上有m个设计方案,第k个设计方案会在宫殿和瞭望塔之间修建Tk条双向道路,
第i条道路连接着瞭望塔ai,长度为Li。
计算到每一个瞭望塔的最短路之和是一个繁重的工程,本来Cedyks想用广为流传的SPFA算法
来求解,但是因为他的butter(缓冲区)实在是太小了,他只能转而用原始的贝尔福特曼算法
来计算,算法的流程大概如下:
1:定义宫殿是0号点,第i个瞭望塔是i号点,双向边(ui,vi,Li)为一条连接ui和vi的双向道路。
令d为距离数组,最开始d0=0,di=10^18(i∈[1,n])。
2:令辅助数组c=d。依次对于每一条边(ui,vi,wi)进行增广,
cui=min(cui,dvi+wi),
cvi=min(cvi,dui+wi)。
3:令t为c和d中不一样的位置个数,即令S={i|ci!=di},则t=S。若t=0,说明d
就是最终的最短路,算法结束。否则令d=c,回到第二步。
因为需要计算的设计方案实在是太多了,所以Cedyks雇佣了一些人来帮他进行计算。
为了避免这些人用捏造出来的数据偷懒,他定义一个设计方案的校验值为在这个方案
上运行贝尔福特曼算法每一次进入第三步t的和。他会让好几个雇佣来的人计算同样
的设计方案,并比对每一个人给出的校验值。
你是Cedyks雇佣来的苦力之一,聪明的你发现在这个情形下计算最短路的长度的和
是一件非常简单的事情。但是寄人篱下不得不低头,你不得不再计算出每一个方案
的校验值来交差。

Solution

考场上不会判一个点相同时间被相同距离更新多次的情况...
只需要考虑关键点能够更新到的点就可以了
显然能更新到的点是一个区间
二分这个左右端点
如何判断一个点 \(y\) ,能否被关键点 \(x\) 更新?
设 \(d=|x-y|\)
判断 \([y-d,y+d]\) 之间是否存在其他的关键点到 \(y\) 的距离更小
分别考虑 \(y\) 左右两边的情况:
以左边为例,设可以更新 \(y\) 的点为 \(p\),\(w\) 为到 \(1\) 的距离:
要查找 \(w[x]-w[p]+l\) 的最小值,维护一个 \(max(w[p]-l)\) 即可

注意当两个关键点同时可以更新一个点的时候,要以更新的时间为第二关键字,编号为第三关键字

#include<bits/stdc++.h>
using namespace std;
template<class T>void gi(T &x){int f;char c;for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
}
typedef long long ll;
const int N=2e5+10;
int n,Q,m,L[N],R[N],mx,Log[N],sx[N][20],sd[N][20];ll w[N],v1[N],v2[N];
struct data{int x,l;}a[N];
inline bool operator <(data i,data j){return i.x<j.x;}
inline int Max(int p,int q){if(v1[p]!=v1[q])return v1[p]>v1[q]?p:q;if(a[p].x!=a[q].x)return a[p].x>a[q].x?p:q;return p<q?p:q;
}
inline int Min(int p,int q){if(v2[p]!=v2[q])return v2[p]<v2[q]?p:q;if(a[p].x!=a[q].x)return a[p].x<a[q].x?p:q;return p<q?p:q;
}
inline void build(){mx=Log[m]+1;for(int i=1;i<=m;i++){sd[i][0]=i,sx[i][0]=i;v1[i]=w[a[i].x]-a[i].l,v2[i]=w[a[i].x]+a[i].l;}for(int j=1;j<=mx;j++)for(int i=1;i+(1<<j)-1<=m;i++){int k=i+(1<<(j-1));sd[i][j]=Max(sd[i][j-1],sd[k][j-1]);sx[i][j]=Min(sx[i][j-1],sx[k][j-1]);}
}
inline ll qx(int l,int r){int k=Log[r-l+1];return Min(sx[l][k],sx[r-(1<<k)+1][k]);
}
inline ll qd(int l,int r){int k=Log[r-l+1];return Max(sd[l][k],sd[r-(1<<k)+1][k]);
}
inline bool check(int x,int d,int y){int p=lower_bound(a+1,a+m+1,(data){y-d,0})-a;int q=upper_bound(a+1,a+m+1,(data){y+d,0})-a-1;int z=lower_bound(a+1,a+m+1,(data){y,0})-a;if(q>=z){int t1=qx(z,q);ll vr=abs(w[y]-w[a[x].x])+a[x].l;if(v2[t1]-w[y]<vr || (v2[t1]-w[y]==vr && abs(a[t1].x-y)<abs(y-a[x].x)))return false;if(v2[t1]-w[y]==vr && abs(a[t1].x-y)==abs(y-a[x].x) && t1<x)return false;}if(p<z){int t1=qd(p,z-1);ll vr=abs(w[y]-w[a[x].x])+a[x].l;if(w[y]-v1[t1]<vr || (w[y]-v1[t1]==vr && abs(a[t1].x-y)<abs(y-a[x].x)))return false;if(w[y]-v1[t1]==vr && abs(a[t1].x-y)==abs(y-a[x].x) && t1<x)return false;}return true;
}
inline int getL(int x){int l=1,r=a[x].x,mid,ret=r;while(l<=r){mid=(l+r)>>1;if(check(x,a[x].x-mid,mid))ret=mid,r=mid-1;else l=mid+1;}return ret;
}
inline int getR(int x){int l=a[x].x,r=n,mid,ret=l;while(l<=r){mid=(l+r)>>1;if(check(x,mid-a[x].x,mid))ret=mid,l=mid+1;else r=mid-1;}return ret;
}
inline void solve(){gi(m);for(int i=1;i<=m;i++)gi(a[i].x),gi(a[i].l);sort(a+1,a+m+1);build();ll ans=0;for(int i=1;i<=m;i++)L[i]=getL(i),R[i]=getR(i),ans+=R[i]-L[i]+1;printf("%lld\n",ans);
}
int main(){freopen("pp.in","r",stdin);freopen("pp.out","w",stdout);cin>>n>>Q;for(int i=2;i<=n;i++)Log[i]=Log[i>>1]+1;for(int i=2;i<=n;i++)gi(w[i]),w[i]+=w[i-1];while(Q--)solve();return 0;
}

转载于:https://www.cnblogs.com/Yuzao/p/9073124.html

bzoj 5308: [Zjoi2018]胖相关推荐

  1. bzoj 5308 [ZJOI2018] 胖

    bzoj 5308 [ZJOI2018] 胖 Link Solution \(\text{ZJOI2018}\) 最简单的一道题 首先看数据范围,大概就是每次 \(O(k\log n)\) 或者 \( ...

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

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

  3. bzoj5308[Zjoi2018]胖(线段树,二分,st表)

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

  4. BZOJ5308 ZJOI2018胖

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

  5. yyb省选前的一些计划

    突然意识到有一些题目的计划,才可以减少大量查水表或者找题目的时间. 所以我决定这样子处理. 按照这个链接慢慢做. 当然不可能只做省选题了. 需要适时候夹杂一些其他的题目. 比如\(agc/arc/cf ...

  6. Loj #2529. 「ZJOI2018」胖

    Loj #2529. 「ZJOI2018」胖 题目描述 Cedyks 是九条可怜的好朋友(可能这场比赛公开以后就不是了),也是这题的主人公. Cedyks 是一个富有的男孩子.他住在著名的 The P ...

  7. 【BZOJ5213】[ZJOI2018]迷宫(神仙题)

    [BZOJ5213][ZJOI2018]迷宫(神仙题) 题面 BZOJ 洛谷 题解 首先可以很容易的得到一个\(K\)个点的答案. 构建\(K\)个点分别表示\(mod\ K\)的余数.那么点\(i\ ...

  8. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  9. S-T平面图中利用最短路求最小割(BZOJ 1001)

    BZOJ 1001: [BeiJing2006]狼抓兔子 最小割 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 现在小朋友们最喜欢 ...

最新文章

  1. 剑指offer 刷题 01
  2. 用TensorFlow基于神经网络实现井字棋(含代码)
  3. 如何用 Nacos 构建服务网格生态
  4. Java 中正确获取中文字符串长度
  5. C4C Cloud Application Studio做ABSL开发的一些性能方面的最佳实践
  6. python实用脚本 知乎_停课不停学|38 个免费 Python 项目合集,从小白到老司机!...
  7. 可怕!你没看错,这次确实是纯手工实现一个MyBatis框架!
  8. https方式nginx 代理tomcat访问不带www的域名301重定向跳转到www的域名帮助seo集中权重...
  9. 基于jsp(java)学生成绩管理系统的设计和实现
  10. AT+CIPSNTPTIME?总是返回 1970年1月1日00:00:00
  11. STM32学习(电容触摸按键)
  12. 专业抠图软件Super PhotoCut Pro for Mac
  13. icem合并面网格_ICEM CFD中合并多个网格
  14. 战地5未能达到服务器带宽,《战地5》游戏bug汇总以及解决方案介绍
  15. mysql http_put_洪永佳 - SegmentFault 思否
  16. IAR for 430 如何建一个简易工程
  17. 微信小程序拼团进度,显示当前刻度,未到刻度点时显示在中间
  18. NNDL 2022秋
  19. 统计学习方法chapter1
  20. 码农的自我修养 - 关于ARM你需要知道的

热门文章

  1. 深度学习入门之AdaGrad
  2. 单元测试-JMockit
  3. 双击计算机显示远程过程调用失败,Win7提示”远程过程调用失败且未执行”怎么办...
  4. getch和ungetch的使用
  5. springboot项目报错:ERROR 9112 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] 的解决办法
  6. Log4j的主要作用是什么?Log4j都由哪些部分组成?【面试常问】
  7. 新版火狐 拖 功能_Firefox 28的新功能
  8. RemoteApp Tool
  9. tinyurl_如何查看TinyUrl真正链接到的位置
  10. EasyExcel导入数据