您的位置:首页 > 其它

HDU 5738 Eureka

2016-07-23 10:52 369 查看
时限卡的好紧,G++ 3400ms过的,C++超时了。

双关键字排序,然后从左一个一个点看过去,假设第i个点必选,然后对i之后的点按照i这个点为原点进行极角排序,极角相同的排在一起(可以除gcd之后排序),然后统计一下即可。重点需要注意一下。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}

const int maxn=1000+10;
const LL mod=1e9+7;
LL h[maxn];
struct X { LL x,y; } p[maxn],t[maxn];
int T,n,num[maxn];

bool cmp( X a,X b)
{
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}

LL gcd(LL a,LL b) { if(b==0) return a; return gcd(b,a%b); }

int main()
{
h[0]=1; for(int i=1;i<=1000;i++) h[i]=(2*h[i-1])%mod;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%lld%lld",&p[i].x,&p[i].y);
sort(p,p+n,cmp); p
.x=p
.y=(LL)0x7fffffff;
for(int i=0;i<n;)
{
int f=i;
for(;;f++) if(p[i].x!=p[f].x||p[i].y!=p[f].y) break;
for(int j=i;j<f;j++) num[j]=f-i-(j-i); i=f;
}
LL ans=0;
for(int i=0;i<n;i++)
{
ans=(ans+h[num[i]-1]-1)%mod;
int sz=0;
for(int j=i+num[i];j<n;j++)
{
t[sz].x=p[j].x-p[i].x,t[sz].y=p[j].y-p[i].y;
LL GCD=gcd(abs(t[sz].x),abs(t[sz].y));
t[sz].x=t[sz].x/GCD, t[sz].y=t[sz].y/GCD; sz++;
}
sort(t,t+sz,cmp); t[sz].x=t[sz].y=(LL)0x7FFFFFFF;
int cnt=1;
for(int j=0;j<sz;j++)
{
if(t[j].x==t[j+1].x&&t[j].y==t[j+1].y) cnt++;
else ans=(ans+h[num[i]-1]*(h[cnt]-1)%mod)%mod,cnt=1;
}
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: