[玄学分治 || 线段树] BZOJ 2675 Bomb & Tsin 1322 Bomb(李超)
来源:互联网 发布:淘宝客怎么算恶意下单 编辑:程序博客网 时间:2024/05/20 09:11
玄学分治做法 %%% http://www.cnblogs.com/ccz181078/p/5603283.html
三个点(x1,y1),(x2,y2),(x3,y3)的两两曼哈顿距离和为2(max(x1,x2,x3)+max(y1,y2,y3)-min(x1,x2,x3)-min(y1,y2,y3))
四项三个点 由抽屉原理 必至少有两项是同一个点的
那么最大值就是
max((x+y)max-xmin-ymin,xmax+ymax-(x+y)min,(x-y)max-xmin+ymax,xmax-ymin-(x-y)min)
最小值分治跟最近点对很相似
这里为了防卡 把xy交换了
#include<cstdio>#include<cstdlib>#include<algorithm>#include<cmath>using namespace std;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++;}inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=100005;struct Point{ int x,y; void read(){ ::read(x); ::read(y); } bool operator < (const Point &B)const { return x==B.x?y<B.y:x<B.x; }}P[N],tmp[N];int pnt=0;bool cmp(Point A,Point B){ return A.y==B.y?A.x<B.x:A.y<B.y;}inline int Calc(Point A,Point B,Point C){ return max(A.x,max(B.x,C.x))-min(A.x,min(B.x,C.x))+max(A.y,max(B.y,C.y))-min(A.y,min(B.y,C.y));}int n;int Ans=1<<30;inline void Solve(int l,int r){ if (r-l<15){ for (int i=l;i<=r;i++) for (int j=i+1;j<=r;j++) for (int k=j+1;k<=r;k++) Ans=min(Ans,Calc(P[i],P[j],P[k])); return; } int mid=(l+r)>>1; Solve(l,mid); Solve(mid,r); pnt=0; for (int i=mid;i<=r;i++) if (abs(P[i].x-P[mid].x)<Ans) tmp[++pnt]=P[i]; else break; for (int i=mid-1;i>=l;i--) if (abs(P[i].x-P[mid].x)<Ans) tmp[++pnt]=P[i]; else break; sort(tmp+1,tmp+pnt+1,cmp); int L=1,R; for (R=3;R<=pnt;R++){ while (abs(tmp[R].y-tmp[L].y)>=Ans) L++; for (int j=L;j<R;j++) for (int k=j+1;k<R;k++)Ans=min(Ans,Calc(tmp[j],tmp[k],tmp[R])); }}int main(){ int xmax,xmin,ymax,ymin,xpymax,xpymin,xmymax,xmymin; freopen("t.in","r",stdin); freopen("t.out","w",stdout); xmax=ymax=xpymax=xmymax=-1<<30; xmin=ymin=xpymin=xmymin=1<<30; read(n); for (int i=1;i<=n;i++){ P[i].read(); swap(P[i].x,P[i].y); xmax=max(xmax,P[i].x),xmin=min(xmin,P[i].x); ymax=max(ymax,P[i].y),ymin=min(ymin,P[i].y); xpymax=max(xpymax,P[i].x+P[i].y),xpymin=min(xpymin,P[i].x+P[i].y); xmymax=max(xmymax,P[i].x-P[i].y),xmymin=min(xmymin,P[i].x-P[i].y); } printf("%d\n",2*max(max(xpymax-xmin-ymin,xmax+ymax-xpymin),max(xmymax-xmin+ymax,xmax-ymin-xmymin))); sort(P+1,P+n+1); Solve(1,n); printf("%d\n",Ans*2); return 0; }
这道题正解是不是线段树啊
我想了想三个点的相对位置 一共七八种吧 好麻烦
不过Claris把坐标转来转去 最终发现不对称的只有两种了
厉害啊
http://www.cnblogs.com/clrs97/p/4872267.html
跟最近点对很相似
0 0
- [玄学分治 || 线段树] BZOJ 2675 Bomb & Tsin 1322 Bomb(李超)
- 【bzoj 3821】玄学 线段树
- Bomb
- Bomb
- Bomb
- Bomb
- Bomb
- bomb
- Bomb
- Bomb
- bomb
- bzoj 3821 玄学 [线段树+归并排序]
- BZOJ 1568 李超线段树
- BZOJ 3165 李超线段树
- hdu3555 Bomb
- Bomb lab
- Fork bomb
- ZIP BOMB
- AngularJS 服务
- ftp的url格式
- 静态代码分析工具汇总
- 李宏毅--Machine Learning and having it deep and structured
- 类自动载入、开发一个PSR-0的基础框架
- [玄学分治 || 线段树] BZOJ 2675 Bomb & Tsin 1322 Bomb(李超)
- Linux Top 命令结果说明
- 范式应用于数据库设计
- 两层循环同步进行
- 二,leveldb源码分析(status)
- http 请求字符串 包含 请求行 请求头 求情正文
- 2016年年终总结
- Spark算子:RDD键值转换操作(2)–combineByKey、foldByKey
- android的m、mm、mmm编译命令的使用