2015 北京网络赛 C Protecting Homeless Cats hihoCoder 1229 树状数组

题意:求在平面上 任意两点连线,原点到这个点的距离小于d的点对有多少个,n=200000;

解: 以原点为圆心做一个半径为d的圆,我们知道圆内的点和园内以外的点的连线都是小于d的还有,圆内和园内的点联线也是小于d的,那么需要处理的是圆外和圆外的点。

以每个圆外的点 向圆做切线 然后我们知道有绿色点区域是允许和他搭配的

那么这些点有一个共同特点 那就他们和圆的切线都在 那个点切点的一侧,这样我们就让每个点 转化为两个切点,然后按照极角排序,求出那些不想交区间就是不合法的

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
const int maxn=200005*2;
const double eps=0.000000000001;
const double PI=acos(-1.0);
struct Point
{
    double x,y;
    Point(double cx=0,double cy=0)
    {
        x=cx; y=cy;
    }
};
struct Circle{
  Point c;
  double r;
  Circle(Point c,double r):c(c),r(r){}
  Point point(double a)
              {
                  return Point(c.x+cos(a)*r,c.y+sin(a)*r);
              }
};
int dcmp(double a)
{
    if(fabs(a)<eps)return 0;
    return a<0?-1:1;
}
double angle(Point v)
{
    return atan2(v.y,v.x);
}
Point operator -(Point A, Point B)
{
    return Point(A.x-B.x,A.y-B.y);
}
double Length(Point c)
{
    return sqrt(c.x*c.x+c.y*c.y);
}
Point Rotate(Point A, double rad)
{
    return Point(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
void getTangents(Point p, Circle C,double &A, double &B)
{
    Point u=p;
    double dist=Length(u);
    if(dcmp(dist-C.r)==0){
      double a=atan2(p.y,p.x);
      if(a<0){
        B=A=a+PI*2;
      }else A=B=a;
   }else{
       double ang=acos(C.r/dist);
       Point t=Rotate(u,ang);
       double a=atan2(t.y,t.x);
       if(a<0)
       {
           A=a+PI*2;
           B=a-ang*2+PI*2;
       }else{
           A=a;
           B=a-ang*2;
           if(B<0)B+=PI*2;
       }
    }
}
Point P[maxn];
struct Elem
{
    double L,R;
    int cL,cR;
    bool operator <(const Elem &rhs)const
    {
        return cL<rhs.cL||(cL==rhs.cL&&cR<rhs.cR);
    }
}E[maxn];
double JJ[maxn*2];
int C[maxn*2];
int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int v,int n)
{
    if(x<=0)return ;
    while(x<=n)
    {
        C[x]+=v;
        x+=lowbit(x);
    }
}
int sum(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=C[x];
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    int n;
    double d;
    while(scanf("%d%lf",&n,&d)==2)
    {
        LL ge=0,nu=0,cc=0;
        Circle c(Point(0,0),d);
        for(int j=0; j<n; j++)
        {
            scanf("%lf%lf",&P[nu].x,&P[nu].y);
            if(dcmp(Length(P[nu])-d)<0)
            {
                ge++;
            }
            else
            {
                getTangents(P[nu],c,E[nu].L,E[nu].R);
                if(E[nu].L>E[nu].R)swap(E[nu].L,E[nu].R);
                JJ[cc++]=E[nu].L;JJ[cc++]=E[nu].R;
                nu++;
            }
        }
        sort(JJ,JJ+cc);
        ge=1;
        for(int i=1; i<cc; i++)
        {
            if(dcmp(JJ[i]-JJ[ge-1])>0)JJ[ge++]=JJ[i];
        }
        cc=ge;
        for(int i=0; i<=cc; i++)C[i]=0;
        for(int i=0; i<nu; i++)
        {
            E[i].cL=upper_bound(JJ,JJ+cc,E[i].L)-JJ;
            E[i].cR=upper_bound(JJ,JJ+cc,E[i].R)-JJ;
            add(E[i].cL,1,cc);
            add(E[i].cR,-1,cc);
        }
        sort(E,E+nu);
        LL buhefa=0;
        for(int i=0; i<nu; i++)
        {
            LL d1= sum(E[i].cR);
            LL d2= sum(E[i].cL-1);
            buhefa+=d1-d2;
            add(E[i].cL,-1,cc);
            add(E[i].cR,1,cc);
        }
        LL nn=n;
        LL ans=nn*(nn-1)/2-buhefa;
        printf("%lld\n",ans);
    }
    return 0;
}
/*
4 10
0 2
2 0
0 100
100 0
*/

时间: 2024-11-13 06:55:46

2015 北京网络赛 C Protecting Homeless Cats hihoCoder 1229 树状数组的相关文章

2015北京网络赛A题The Cats&#39; Feeding Spots

题意:给你一百个点,找个以这些点为中心的最小的圆,使得这个圆恰好包含了n个点,而且这个圆的边界上并没有点 解题思路:暴力枚举每个点,求出每个点到其他点的距离,取第n大的点,判断一下. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<memory.h> 6 using namespace std; 7 const i

2015北京网络赛 Couple Trees 倍增算法

2015北京网络赛 Couple Trees 题意:两棵树,求不同树上两个节点的最近公共祖先 思路:比赛时看过的队伍不是很多,没有仔细想.今天补题才发现有个 倍增算法,自己竟然不知道.  解法来自 qscqesze ,这个其实之前如果了解过倍增的话还是不是很难,不过这题的数据也不是很给力,极限数据理论上是过不了的.  其他解法有树链剖分?并不是很清楚.就这样水过了吧... 1 #include <iostream> 2 #include <cstdio> 3 #include &l

2015北京网络赛 D-The Celebration of Rabbits 动归+FWT

2015北京网络赛 D-The Celebration of Rabbits 题意: 给定四个正整数n, m, L, R (1≤n,m,L,R≤1000). 设a为一个长度为2n+1的序列. 设f(x)为满足x≤ai≤m+x且ai的异或和为0 的序列a的个数. 求 ∑Rx=Lf(x)mod1000000007 思路:因为对于每一个第一次分配后的a序列对应唯一的x,所以我们就枚举x然后在求序列的个数.

北邮校赛 F. Gabriel&#39;s Pocket Money(树状数组)

F. Gabriel's Pocket Money 2017- BUPT Collegiate Programming Contest - sync 时间限制 2000 ms 内存限制 65536 KB 题目描述 For centuries, Heaven has required its young angels to live and study among humans in order to become full-fledged angels. This is no different

2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ&#39;s Salesman 【离散化+树状数组维护区间最大值】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 919    Accepted Submission(s): 290 Problem Description YJJ is a salesman who h

2015 北京网络赛 E Border Length hihoCoder 1231 树状数组 (2015-11-05 09:30)

#1231 : Border Length 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Garlic-Counting Chicken is a special species living around the Lake of Peking University. A Garlic-Counting Chicken always flies out from home in the morning, goes to some fixed points looki

Hiho coder 1236 2015 北京网络赛 Score

五维偏序..一开始被吓到了,后来知道了一种BITSET分块的方法,感觉非常不错. 呆马: 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <vector> 7 #include <bitset> 8 #define inf 100000000

acm 2015北京网络赛 F Couple Trees 主席树+树链剖分

提交 题意:给了两棵树,他们的跟都是1,然后询问,u,v 表 示在第一棵树上在u点往根节点走 , 第二棵树在v点往根节点走,然后求他们能到达的最早的那个共同的点 解: 我们将第一棵树进行书链剖,然后第二棵树采用主席树,他的信息来自他的父亲节点,每个点存他在第一棵树 树链剖分后的位置,这样我们每次查询uv的时候我们只要 我们选取u和top[u]这段区间在主席树v这颗树上找,在这个区间能取到的最大值,一旦存在,这个最大值就我们要的,这个点保存着他到根节点这条路上所有点在第一棵树剖分后的位置 #inc

hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题

题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给定的学生成绩都异或上一次的答案 先将学生按每一门成绩都排一次序 这里将学生分块成sqrt(n)的块数,然后在当前块中用bitset容器来记录含有学生的状态 这里可以记录状态的前缀和,因为比后面成绩好的,必然比前面的学生的成绩也好 查询的时候只要查到正好比他高的学生属于哪一块,这样只要访问sqrt(n