[Ahoi2008]Rectangle 解题报告
来源:互联网 发布:一个域名绑定多个ip 编辑:程序博客网 时间:2024/05/29 13:11
又是喜闻乐见的只会傻逼做法的题。。跟我跑得差不多快的人都写了1K,我写了快4K。。
并不知道他们怎么搞的,说下我的做法:
考虑按x从大到小的扫描线,每次在矩形的左下角
在k-d树上查询的时候因为是dfs,所以可以各种剪枝。建树的时候可以类似划分树一样建,就是
最后口胡一下科学的做法该怎么搞(其实我感觉kd树就挺科学的。。)。如果我们对扫描线用cdq分治的话,就相当于是有一坨点,然后查询前缀矩形max,这个就可以用扫描线+bit搞出来。时间复杂度就是
我看别人都写得特别短。。听说是暴力乱搞。。不知道他们怎么搞的。。
代码:
#include<cstdio>#include<iostream>using namespace std;#include<algorithm>#include<cstdlib>#include<cstring>#include<cmath>const int N=2e5+5;struct KS{ int lx,rx,ly,ry,max;}kdtree[N<<2];struct PS{ int x,y;}point[N];int a[N],b[N],tmp[N];int pos[N];bool cmp1(const int &a,const int &b){ return point[a].x<point[b].x;}bool cmp2(const int &a,const int &b){ return point[a].y<point[b].y;}const int inf=0x7fffffff;void build(int node,int depth,int tot){ //printf("---%d,%d---\n",node,tot); kdtree[node]=(KS){point[a[0]].x,point[a[tot-1]].x,point[b[0]].y,point[b[tot-1]].y,-1}; if(tot==1){ //printf("%d:%d\n",node,a[0].i); pos[a[0]]=node; } else{ /*printf("a="); for(int i=0;i<tot;++i)printf("%d(%d) ",a[i].i,a[i].x); puts(""); printf("b="); for(int i=0;i<tot;++i)printf("%d ",b[i].i); puts("");*/ //if(rand()&1){ if(depth){ //puts("x!"); int ttot=0; for(int i=0;i<tot;++i) if(point[b[i]].x<point[a[tot>>1]].x){ tmp[ttot++]=b[i]; //printf("Get:%d %d %d\n",b[i].i,b[i].x,a[tot>>1].x); } for(int i=0;i<tot;++i) if(point[b[i]].x>=point[a[tot>>1]].x) tmp[ttot++]=b[i]; memcpy(b,tmp,sizeof(int)*tot); } else{ //puts("y!"); int ttot=0; for(int i=0;i<tot;++i) if(point[a[i]].y<point[b[tot>>1]].y) tmp[ttot++]=a[i]; for(int i=0;i<tot;++i) if(point[a[i]].y>=point[b[tot>>1]].y) tmp[ttot++]=a[i]; memcpy(a,tmp,sizeof(int)*tot); } /*printf("a="); for(int i=0;i<tot>>1;++i)printf("%d ",a[i].i); puts(""); printf("b="); for(int i=0;i<tot>>1;++i)printf("%d ",b[i].i); puts("");*/ build(node<<1,depth^1,tot>>1); memcpy(a,a+(tot>>1),sizeof(int)*(tot-(tot>>1))); memcpy(b,b+(tot>>1),sizeof(int)*(tot-(tot>>1))); build(node<<1|1,depth^1,tot-(tot>>1)); }}void update(int node,int A){ //cout<<"update("<<node<<','<<A<<")\n"; for(;node;node>>=1)kdtree[node].max=max(kdtree[node].max,A);}bool query(int node,int rx,int ry,int downlimit){ //printf("%d={lx=%d,rx=%d,ly=%d,ry=%d,max=%d} (%d,%d)\n",node,kdtree[node].lx,kdtree[node].rx,kdtree[node].ly,kdtree[node].ry,kdtree[node].max,rx,ry); if(kdtree[node].max<downlimit)return 0; if(kdtree[node].rx<=rx&&kdtree[node].ry<=ry)return kdtree[node].max>downlimit; else{ if(kdtree[node].lx<=rx&&kdtree[node].ly<=ry){ if(query(node<<1,rx,ry,downlimit))return 1; if(query(node<<1|1,rx,ry,downlimit))return 1; } return 0; }}struct RS{ int x1,y1; int x2,y2; int i; bool operator < (const RS & o)const{ return x2<o.x2; }}rec[N];char * cp=(char *)malloc(10000000);void in(int &x){ while(*cp<'0'||*cp>'9')++cp; for(x=0;*cp>='0'&&*cp<='9';)x=x*10+(*cp++^'0');}int main(){ freopen("bzoj_1790.in","r",stdin); fread(cp,1,10000000,stdin); int n; in(n); for(int i=n;i--;){ in(rec[i].x1),in(rec[i].y1); in(rec[i].x2),in(rec[i].y2); rec[i].i=i; point[i]=(PS){rec[i].x1,rec[i].y1}; b[i]=a[i]=i; } sort(a,a+n,cmp1); sort(b,b+n,cmp2); build(1,0,n); //for(int i=n;i--;)printf("pos(%d)=%d\n",i,pos[i]); sort(rec,rec+n); int ans=0; for(int i=n;i--;){ //printf("(%d,%d)-(%d,%d) i=%d\n",rec[i].x1,rec[i].y1,rec[i].x2,rec[i].y2,rec[i].i); ans+=query(1,rec[i].x1-1,rec[i].y1-1,rec[i].y2); update(pos[rec[i].i],rec[i].y2); } printf("%d\n",ans);}
总结:
①矩阵/高维问题可以用cdq分治搞一维,这样时间/空间都会比较好。
②k-d树建树的时候可以像划分树一样建,这样就是
0 0
- [Ahoi2008]Rectangle 解题报告
- HDU 4495 Rectangle 解题报告
- LeetCode-Rectangle Area 解题报告
- [LeetCode] Largest Rectangle in Histogram 解题报告
- [LeetCode]Largest Rectangle in Histgram,解题报告
- [CF335D]Rectangle And Square 解题报告
- [leetcode] 85. Maximal Rectangle 解题报告
- [leetcode] 223. Rectangle Area 解题报告
- [LeetCode] Largest Rectangle in Histogram 解题报告
- [leetcode] 391. Perfect Rectangle 解题报告
- 【LeetCode】Construct the Rectangle 解题报告
- [Leetcode] 223. Rectangle Area 解题报告
- [Leetcode] 391. Perfect Rectangle 解题报告
- [leetcode] 391. Perfect Rectangle 解题报告
- [Leetcode] 492. Construct the Rectangle 解题报告
- hdu 4419 Colourful Rectangle 杭州赛区 1010 (解题报告)
- 解题报告 之 POJ 2559 Largest Rectangle in a Histogram
- [leetcode] 84. Largest Rectangle in Histogram 解题报告
- 约瑟夫环问题(循环链表)
- 设计模式(8)之策略模式
- 【BZOJ1266】[AHOI2006]上学路线route【最短路图】【最小割】
- 【php基础 Xdebug】linux下Xdebug的安装与使用
- bzoj 1790: [Ahoi2008]Rectangle 矩形藏宝地
- [Ahoi2008]Rectangle 解题报告
- 02@设计模式概览
- Linux Nginx安装以及可能出现错误
- LeetCode 217 Contains Duplicate II java
- iframe间传值
- 网络知识
- java安全-类加载器
- C++实验4—乘法口诀表
- Java多线程面试问题