博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[ZJOI2018]胖
阅读量:4927 次
发布时间:2019-06-11

本文共 2239 字,大约阅读时间需要 7 分钟。

有数据就是好

以及

对于\(k\)个关键点中的每一个关键点\(a\),二分它能更新到的左端点和右端点

\(d=|a−p|\),则\(a\)可以更新\(p\)当且仅当区间\([p−d,p+d]\)中的关键点到\(p\)的距离没有比\(a\)更优的

\(st\)表维护两个东西 : 区间中到右端点最短的距离 , 区间中到右端点最短的距离

具体细节见代码

#include
#include
#include
#include
#define debug(...) fprintf(stderr,__VA_ARGS__)#define Debug(x) cout<<#x<<"="<
<
pii;const LL INF=1e18;inline LL read(){ register LL x=0,f=1;register char c=getchar(); while(c<48||c>57){if(c=='-')f=-1;c=getchar();} while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar(); return f*x;}const int MAXN=2e5+5;const int logN=19;LL a[MAXN],p[MAXN],len[MAXN],st1[MAXN][logN+1],st2[MAXN][logN+1];int log2[MAXN];int n,m,k;pii pp[MAXN];inline LL dis(int x,int y){ if(x>y) return INF; return a[y-1]-a[x-1];}inline LL calc1(int l,int r){ if(l>r) return INF; int len=log2[r-l+1]; int pos1=l+(1<
<
= int pos2=upper_bound(p+1,p+k+1,r)-p-1;// > if(pos1>pos2) return INF; return calc1(pos1,pos2)+dis(p[pos2],r);}inline LL calc2(int l,int r){ if(l>r) return INF; int len=log2[r-l+1]; int pos=r-(1<
pos2) return INF; return calc2(pos1,pos2)+dis(l,p[pos1]);}inline bool check1(int x,int t){ if(t<1||t>n) return false; int pos=p[x],d=pos-t,l=t-d,r=t+d; LL zuo=cal1(l,t),you=cal2(t,r-1); LL dist=min(zuo,you),now=dis(t,pos)+len[x]; if(now
n) return false; int pos=p[x],d=t-pos,l=t-d,r=t+d; LL zuo=cal1(l+1,t),you1=cal2(t,r-1),you2=cal2(t,r); LL dist=min(zuo,you2),now=dis(pos,t)+len[x]; if(now
>1]+1; while(m--){ k=read(); for(int i=1;i<=k;i++){ int x=read(),y=read(); pp[i]=pii(x,y); } sort(pp+1,pp+k+1); for(int i=1;i<=k;i++){ p[i]=pp[i].first,len[i]=pp[i].second; st1[i][0]=len[i],st2[i][0]=len[i]; } for(int j=1;j<=18;j++) for(int i=1;i<=k;i++){ int x=i+(1<<(j-1)),y=i+(1<
k) break; st1[i][j]=min(st1[i][j-1]+dis(p[x-1],p[y]),st1[x][j-1]);//区间中到右端点最近的 st2[i][j]=min(st2[i][j-1],st2[x][j-1]+dis(p[i],p[x]));//区间中到左端点最近的 } LL ans=0; for(int i=1;i<=k;i++){ int L=1,R=p[i]; while(L+1
>1; if(check1(i,mid)) R=mid; else L=mid+1; } if(check1(i,R-1)) R--; int pos1=R; L=p[i],R=n; while(L+1
>1; if(check2(i,mid)) L=mid; else R=mid-1; } if(check2(i,L+1)) L++; ans+=L-pos1+1; } printf("%lld\n",ans); }}

转载于:https://www.cnblogs.com/lizehon/p/10589464.html

你可能感兴趣的文章
Navicat使用ssh连接数据库
查看>>
python[pip源配置]
查看>>
bzoj4820: [Sdoi2017]硬币游戏
查看>>
iOS UIScrollView
查看>>
常见HTTP状态码
查看>>
vim 空格和换行的删除和替换
查看>>
ionic 入门学习
查看>>
[python]pickle和cPickle
查看>>
末日了,天是灰色的。
查看>>
Vuejs vm对象详解
查看>>
hdu 3342 Legal or Not 拓排序
查看>>
ssh免密码登录
查看>>
Django settings.py 的media路径设置
查看>>
自定义RatingBar的一个问题(只显示显示一个星星)
查看>>
jmeter提取正则表达式中所有关联值-----我想获取所有的ID
查看>>
[bzoj1819] [JSOI]Word Query电子字典
查看>>
【MCU】【STM32】1.cube MX库使用笔记
查看>>
web 本地存储 (localStorage、sessionStorage)
查看>>
iOS中多控制器的使用
查看>>
python标准库之文本
查看>>