[阈值] SPOJ RECTANGL
来源:互联网 发布:淘宝拍卖烂尾楼 编辑:程序博客网 时间:2024/06/05 05:05
详见 一类算法复合的方法
大概就是把坐标都离散了
按照某x坐标上的点数分类
如果矩形的某边是大类 只有
否则所有小类 把所有能构成的线段放进hash表 只有
再一次体验了unordered_map的感人速度
#include<cstdio>#include<cstdlib>#include<algorithm>#include<vector>#include<cmath>#include<tr1/unordered_map> #include<tr1/unordered_set> #define pb push_backusing namespace std;using namespace std::tr1;typedef vector<int> VI;typedef long long ll;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*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=250005;int sx[N],icnt;inline int Bin(int x){ return lower_bound(sx+1,sx+icnt+1,x)-sx;}int n;int x[N],y[N];VI Y[N];int cnt[N];unordered_set<int> Set;//unordered_map<ll,int> Map;//typedef unordered_map<ll,int>::iterator IT;ll AA,AB,BB;const int M=12500005;const int P=10000007;struct HashMap{ ll k[M]; int v[M],next[M]; int head[P],inum; int&operator[](ll x){ for (int p=head[x%P];p;p=next[p]) if (k[p]==x) return v[p]; ++inum; k[inum]=x; v[inum]=0; next[inum]=head[x%=P]; head[x]=inum; return v[inum]; }}Map;int main(){ freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); for (int i=1;i<=n;i++) read(x[i]),read(y[i]); icnt=0; for (int i=1;i<=n;i++) sx[++icnt]=y[i]; sort(sx+1,sx+icnt+1); icnt=unique(sx+1,sx+icnt+1)-sx-1; for (int i=1;i<=n;i++) y[i]=Bin(y[i]); icnt=0; for (int i=1;i<=n;i++) sx[++icnt]=x[i]; sort(sx+1,sx+icnt+1); icnt=unique(sx+1,sx+icnt+1)-sx-1; for (int i=1;i<=n;i++) x[i]=Bin(x[i]),cnt[x[i]]++,Y[x[i]].pb(y[i]); for (int i=1;i<=icnt;i++) sort(Y[i].begin(),Y[i].end()); int B=sqrt(n); for (int i=1;i<=icnt;i++) if (cnt[i]>B){ for (int j=0;j<cnt[i];j++) Set.insert(Y[i][j]); for (int j=1;j<=icnt;j++){ if (i==j) continue; if (cnt[j]>B){ int c=0; for (int k=0;k<cnt[j];k++) if (Set.count(Y[j][k])) c++; AA+=(ll)c*(c-1)/2; }else{ int c=0; for (int k=0;k<cnt[j];k++) if (Set.count(Y[j][k])) c++; AB+=(ll)c*(c-1)/2; } } Set.clear(); } for (int i=1;i<=icnt;i++) if (cnt[i]<=B) for (int j=0;j<cnt[i];j++) for (int k=j+1;k<cnt[i];k++) Map[((ll)Y[i][j]<<32)+Y[i][k]]++; for (int i=1;i<=Map.inum;i++) BB+=(ll)Map.v[i]*(Map.v[i]-1)/2; /*for (IT i=Map.begin();i!=Map.end();i++) BB+=(ll)i->second*(i->second-1)/2;*/ printf("%lld\n",AA/2+AB+BB); return 0;}
0 0
- [阈值] SPOJ RECTANGL
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- 堆栈
- LeetCode053 Maximum Subarray
- 经典排序算法
- c#notifyIcon 托盘
- 最大子数组之和
- [阈值] SPOJ RECTANGL
- 使用指针时,容易出错的几个地方
- L1-026. I Love GPLT
- 阿里云https证书tomcat配置
- Machine Learning多元线性回归算法及优化
- 004-107-Binary Tree Level Order Traversal II 层序遍历二叉树之二
- 记SDOI2017 Round 1
- Swift数据类型(五)
- LintCode 二叉树的路径和