提交时间:2024-03-31 13:25:59
运行 ID: 27878
#include<iostream> #include<random> #include<cmath> #include<cassert> #include<ctime> #define timeMS (clock()*1000/CLOCKS_PER_SEC) #define int long long using namespace std; const int N=100010; using ull=unsigned long long; mt19937 rng(time(0)); mt19937_64 rngll(time(0)); int rt,ver,ls[N],rs[N],val[N],wei[N];double key[N],mn[N],laz[N]; inline int New(double k,int v){ val[++ver]=v;key[ver]=k,wei[ver]=rng(),ls[ver]=rs[ver]=0,mn[ver]=laz[ver]=1e9; return ver; } inline void push_down(int nd){ mn[nd]=min(mn[nd],laz[nd]); laz[ls[nd]]=min(laz[ls[nd]],laz[nd]); laz[rs[nd]]=min(laz[rs[nd]],laz[nd]); laz[nd]=1e9; } using pii=pair<int,int>; pii split(int nd,double k){ if(!nd)return{0,0}; push_down(nd); if(k<key[nd]){ pii o=split(ls[nd],k); ls[nd]=o.second; return {o.first,nd}; } else{ pii o=split(rs[nd],k); rs[nd]=o.first; return {nd,o.second}; } } int merge(int u,int v){ if(!u||!v)return u|v; if(wei[u]<wei[v]){ push_down(u); rs[u]=merge(rs[u],v); return u; } else{ push_down(v); ls[v]=merge(u,ls[v]); return v; } } void insert(double k,int v){ pii o=split(rt,k); rt=merge(o.first,merge(New(k,v),o.second)); } struct vec{int x,y;}a[N]; inline vec operator-(const vec&A,const vec&B){return (vec){A.x-B.x,A.y-B.y};} inline double len(const vec&A){return sqrt((double)(A.x*A.x+A.y*A.y));} struct cir:public vec{int r;}c[N]; struct line{ int A,B,C; line(){A=B=C=0;} line(const vec&dir,const vec&P){A=dir.y,B=-dir.x,C=dir.x*P.y-dir.y*P.x;} line(int a,int b,int c):A(a),B(b),C(c){} inline double val(const vec&P)const&{return (double)(P.x*A+P.y*B+C);} }; inline double dis(const vec&P,const line&L){return abs(L.val(P))/sqrt(double(L.A*L.A+L.B*L.B));} int n,m,dsu[N]; int find(int x){return dsu[x]==x?x:dsu[x]=find(dsu[x]);} ull t[N]; ull v[N]; void init (){ cin>>n>>m; for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y; for(int i=1;i<=m;i++)cin>>c[i].x>>c[i].y>>c[i].r,t[i]=rngll(); for(int i=1;i<=n;i++)dsu[i]=i; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++)if(len(c[j]-a[i])<c[j].r)v[i]^=t[j]; } } const double pi=acos(-1),eps=1e-6; inline void chkmin(double l,double r,double lim){ pii o=split(rt,l+eps); pii p=split(o.second,r-eps); laz[p.first]=min(laz[p.first],lim); rt=merge(o.first,merge(p.first,p.second)); } void dfs(int p,int nd=rt){ if(!nd)return; push_down(nd); if(len(a[val[nd]]-a[p])<mn[nd])dsu[find(val[nd])]=find(p); dfs(p,ls[nd]); dfs(p,rs[nd]); } bool vis[N]; signed main(){ // freopen("beacons.in","r",stdin); // freopen("beacons.out","w",stdout); init(); for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++)if(v[i]==v[j]){ vec d=a[j]-a[i]; insert(atan2(d.y,d.x),j); } for(int j=1;j<=m;j++){ vec d=c[j]-a[i]; if(len(d)<c[j].r)continue; double theta=atan2(d.y,d.x); double delta=asin((double)c[j].r/len(d)); double lim=sqrt(len(d)*len(d)-c[j].r*c[j].r); if(theta-delta>-pi&&theta+delta<pi)chkmin(theta-delta,theta+delta,lim); else if(theta-delta<=-pi){ chkmin(-pi,theta+delta,lim); chkmin(theta-delta+2*pi,pi,lim); } else{ chkmin(theta-delta,pi,lim); chkmin(-pi,theta+delta-2*pi,lim); } } dfs(i); ver=rt=0; } int cnt=0; for(int i=1;i<=n;i++)cnt+=!vis[find(i)]++; cout<<cnt-1; // cerr<<timeMS; return 0; }