[BZOJ2509][主席树]送分题
来源:互联网 发布:北京的设计公司知乎 编辑:程序博客网 时间:2024/05/29 05:03
题意
给出平面上的M条平行于坐标轴的线段,问有多少个正方形。
这题其实可以
对于一个点
那么暴力就是枚举每个点作为正方形的一个端点,然后枚举正方形的边长再判断。
把平面分成
然后对于每条对角线,题目可以转化为有多少对点在彼此的边长范围内。
主席树处理。
轻松rank(倒数)1
#include <cstdio>#include <cstring>#include <string>#include <iostream>#define N 1010using namespace std;int n,m,Ans,L[N][N],D[N][N],U[N][N],R[N][N];inline void reaD(int &x){ char Ch=getchar();x=0; for(;Ch>'9'||Ch<'0';Ch=getchar()); for(;Ch>='0'&&Ch<='9';x=x*10+Ch-'0',Ch=getchar());}int Sl(int x,int y){return L[x][y]<=y?y:L[x][y]=Sl(x,L[x][y]);}int Sd(int x,int y){return D[x][y]<=x?x:D[x][y]=Sd(D[x][y],y);}int Sr(int x,int y){return R[x][y]>=y?y:R[x][y]=Sr(x,R[x][y]);}int Su(int x,int y){return U[x][y]>=x?x:U[x][y]=Su(U[x][y],y);}struct ft{ struct tr{ int l,r,ls,rs,x; }T[N<<4]; int t,rt[N],tc; void InserT(int &x,int y,int d){ x=++t; T[x]=T[y]; T[x].x++; if(T[x].l==T[x].r) return ; int mid=T[x].l+T[x].r>>1; if(d<=mid) InserT(T[x].ls,T[y].ls,d); else InserT(T[x].rs,T[y].rs,d); } int QuerY(int x,int l,int r){ if(T[x].l==l&&T[x].r==r) return T[x].x; int mid=T[x].l+T[x].r>>1; if(r<=mid) return QuerY(T[x].ls,l,r); if(l>mid) return QuerY(T[x].rs,l,r); return QuerY(T[x].ls,l,mid)+QuerY(T[x].rs,mid+1,r); } void build(int &x,int l,int r){ x=++t; T[x].l=l;T[x].r=r; if(l==r) return; int mid=l+r>>1; build(T[x].ls,l,mid); build(T[x].rs,mid+1,r); } inline void build(){ build(rt[0],1,n+1); tc=t; } inline void clear(){t=tc;} inline void Insert(int x,int L,int d){ rt[x]=rt[x-1]; if(d>0) InserT(rt[x],rt[x-1],L); } inline int Query(int x,int d){return QuerY(rt[x],d,n+1);}}B;inline int calc(int x,int y){ int Res=0;B.clear(); for(int j=1;x<=n;x++,y++,j++){ int k=min(x-U[x][y],y-R[x][y]); if(k>0)Res+=B.Query(j-1,j)-B.Query(j-k-1,j); k=min(D[x][y]-x,L[x][y]-y); B.Insert(j,j+k,k); } return Res;}int main(){ memset(L,-1,sizeof(L)); memset(D,-1,sizeof(D)); memset(R,0x7F,sizeof(R)); memset(U,0x7F,sizeof(U)); reaD(n);reaD(m); for(int i=1,x1,y1,x2,y2;i<=m;i++){ reaD(x1);reaD(y1); reaD(x2);reaD(y2); if(x1==x2){ if(y1>y2) swap(y2,y1); for(int j=y1;j<=y2;j++)L[x1][j]=max(y2,L[x1][j]),R[x1][j]=min(y1,R[x1][j]); }else{ if(x1>x2) swap(x1,x2); for(int j=x1;j<=x2;j++)D[j][y1]=max(x2,D[j][y1]),U[j][y1]=min(x1,U[j][y1]); } } for(int i=0;i<=n;i++) for(int j=0,x,y;j<=n;j++) Sl(i,j),Sd(i,j), Sr(i,j),Su(i,j); B.build(); for(int i=0,x,y,j;i<=n;i++)Ans+=calc(i,0)+calc(0,i+1); return printf("%d\n",Ans),0;}
0 0
- [BZOJ2509][主席树]送分题
- 主席、树、主席树!
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- 主席树
- Cookie在前端中的实践
- 动态链接共享库
- jquery中prop()方法和attr()方法的区别
- Atom输入中文显示问号问题
- SCI论文写作全攻略
- [BZOJ2509][主席树]送分题
- ViewPager的一个应用,用fragment来当页面,可以左右滑动,上面有一条线,来分隔
- 哈弗曼编码
- 游艇出租站最少费用,动态规划算法!
- linux根据uid反查用户名
- 随笔之java面试
- 郝斌的C语言基础 170 补码 下
- jsp实现分页显示信息(数据库、EL表达式、连接池)
- 对javascript的Array中转换方法、栈和队列的理解