【GDOI2017模拟一试4.11】腐女的生日(线段树+维护一次函数)
来源:互联网 发布:摄像头美化软件 编辑:程序博客网 时间:2024/05/01 17:16
Description
腐女要过生日了,pty 想给腐女送礼物,但是腐女所在的教室离pty 的教室太远了,于是pty就拜托会动归和A星的djy帮忙送礼物。djy在学校建立了一个平面直角坐标系,他站在了(0,0)点,腐女在(x0,y0)点,djy每次只能往上下左右四个方向移动一步,中间有n栋矩形教学楼,每个教学楼给出两个对角的坐标,并且保证每栋教学楼的周围区域(如图所示)不会有别的教学楼,即djy可以绕一个教学楼走不会碰到任何障碍,现在djy 想知道从起点到终点不碰到任何教学楼,最短需要多少步。
Solution
一开始我还以为是直接bfs然后优化。
如果只考虑在y走的距离(及上下走的距离)其实一个矩阵的右边界中,只有这条线中才会更改,然后左边界直接改为inf就好了,因为后面右边界会覆盖的,所以不用考虑这个问题。
首先我们知道不会忘左走(最多只忘左走一格)。那么我们最后只用求出上下走的最小距离,然后+x0就好了。那么我们在右边界更新的时候,其实只是更新成两个斜率为1的一次函数而已。更新这个只用维护一个线段上下的纵坐标就好了。
Code
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=1e5+7;int i,j,k,l,n,m,ans,ex,ey,da,yi,er,fen;struct nod{ int x,y,xx,yy,z;}a[maxn*2];bool cmp(nod x,nod y){return x.x<y.x;}struct node{ int b1,b2;}t[maxn*80];void down(int x){ if(!t[x].b1&&!t[x].b2)return; int y=x*2,z=x*2+1,u; if(t[x].b2-t[x].b1>0)u=1;else u=-1; t[y].b1=t[x].b1; t[y].b2=(t[x].b1+t[x].b2+(u<0))/2; t[z].b1=(t[x].b1+t[x].b2+(u<0))/2+u; t[z].b2=t[x].b2; t[x].b1=t[x].b2=0;}void change(int x,int l,int r,int y,int z,int xi,int sh){ if(y>z)return; if(l==y&&r==z){ t[x].b1=xi,t[x].b2=sh; return; } down(x); int mid=(l+r)/2; if(z<=mid)change(x*2,l,mid,y,z,xi,sh); else if(y>mid)change(x*2+1,mid+1,r,y,z,xi,sh); else{ int k=(xi<sh)?1:-1; change(x*2,l,mid,y,mid,xi,xi+k*(mid-y)); change(x*2+1,mid+1,r,mid+1,z,xi+k*(mid-y+1),sh); }}int find(int x,int l,int r,int y){ if(l==r)return t[x].b1; down(x); int mid=(l+r)/2; if(y<=mid)return find(x*2,l,mid,y); else return find(x*2+1,mid+1,r,y);}int main(){ freopen("bl.in","r",stdin); freopen("bl.out","w",stdout);// freopen("fan.in","r",stdin); da=1000001; scanf("%d%d",&ex,&ey);ey+=da; scanf("%d",&n); fo(i,1,n)scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].x,&a[i].yy),a[i].y+=da,a[i].yy+=da; sort(a+1,a+1+n,cmp); change(1,0,da*2,da+1,da*2,1,da); change(1,0,da*2,0,da,da,0); fo(i,1,n){ if(a[i].x>ex)break; yi=find(1,0,da*2,a[i].y-1);er=find(1,0,da*2,a[i].yy+1); fen=(a[i].y+a[i].yy-yi+er)/2; change(1,0,da*2,a[i].y-1,fen,yi,yi+fen-a[i].y+1); if(fen<a[i].yy)change(1,0,da*2,fen+1,a[i].yy+1,er+a[i].yy-fen,er); } ans=find(1,0,da*2,ey)+ex; printf("%d\n",ans);}
1 0
- 【GDOI2017模拟一试4.11】腐女的生日(线段树+维护一次函数)
- 【JZOJ5049】【GDOI2017模拟一试4.11】腐女的生日
- 【GDOI2017模拟一试4.11】腐女的生日
- BZOJ 5049. 【GDOI2017模拟一试4.11】腐女的生日
- {题解}[jzoj5049]【GDOI2017模拟一试4.11】腐女的生日
- 【GDOI2017模拟一试4.11】颜色树
- GDOI2017模拟一试
- JZOJ4774 【GDOI2017模拟9.10】子串 线段树合并维护SAM的fail树信息(CF 666E类似)
- 腐女的生日
- JZOJ 5050. 【GDOI2017模拟一试4.11】颜色树
- 【JZOJ5050】【GDOI2017模拟一试4.11】颜色树
- JZOJ 5050. 【GDOI2017模拟一试4.11】颜色树
- {题解}[jzoj5050]【GDOI2017模拟一试4.11】颜色树
- 5049. 腐女的生日
- [JZOJ5049] 腐女的生日
- JZOJ 5048. 【GDOI2017模拟一试4.11】IQ测试
- {题解}[jzoj5051]【GDOI2017模拟一试4.11】平行宇宙
- 【GDOI2017模拟】树的难题
- 递推递归练习P
- 蓝桥杯-基础试题-试笔-01字串
- 手把手git教程(05)--远程仓库推送和克隆
- Android使用谷歌封装好的api增删查改
- java类型自动装箱拆箱和字符串与基本类型的装换
- 【GDOI2017模拟一试4.11】腐女的生日(线段树+维护一次函数)
- 部署应用到Tomcat服务器
- BZOJ 3809: Gty的二逼妹子序列
- Algorithms
- Java String 格式化示例
- 并发服务器模型实现的方法
- 122.xUtils使用inject取代findViewById的方法填充布局
- 修改主机注册表,将浏览器的默认页面更改为http://www.sina.com.cn.
- 【GDOI2017模拟一试4.11】颜色树(容斥||点剖||DP)